Use new doctemplates, doclayout.
+ Remove Text.Pandoc.Pretty; use doclayout instead. [API change] + Text.Pandoc.Writers.Shared: remove metaToJSON, metaToJSON' [API change]. + Text.Pandoc.Writers.Shared: modify `addVariablesToContext`, `defField`, `setField`, `getField`, `resetField` to work with Context rather than JSON values. [API change] + Text.Pandoc.Writers.Shared: export new function `endsWithPlain` [API change]. + Use new templates and doclayout in writers. + Use Doc-based templates in all writers. + Adjust three tests for minor template rendering differences. + Added indentation to body in docbook4, docbook5 templates. The main impact of this change is better reflowing of content interpolated into templates. Previously, interpolated variables were rendered independently and intepolated as strings, which could lead to overly long lines. Now the templates interpolated as Doc values which may include breaking spaces, and reflowing occurs after template interpolation rather than before.
This commit is contained in:
parent
8959c44e6a
commit
1ee6e0e087
61 changed files with 3414 additions and 3939 deletions
|
@ -13,3 +13,8 @@ source-repository-package
|
||||||
location: https://github.com/jgm/pandoc-citeproc
|
location: https://github.com/jgm/pandoc-citeproc
|
||||||
tag: 6d62678ece91bbb4fe4f5a99695006e1d53c3bae
|
tag: 6d62678ece91bbb4fe4f5a99695006e1d53c3bae
|
||||||
|
|
||||||
|
source-repository-package
|
||||||
|
type: git
|
||||||
|
location: https://github.com/jgm/doctemplates
|
||||||
|
tag: 9b2f5d55f4a2b414b10c4b48aaa7d1169e0ba4d7
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ $if(date)$
|
||||||
$endif$
|
$endif$
|
||||||
</articleinfo>
|
</articleinfo>
|
||||||
$for(include-before)$
|
$for(include-before)$
|
||||||
$include-before$
|
$include-before$
|
||||||
$endfor$
|
$endfor$
|
||||||
$body$
|
$body$
|
||||||
$for(include-after)$
|
$for(include-after)$
|
||||||
$include-after$
|
$include-after$
|
||||||
$endfor$
|
$endfor$
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -28,10 +28,10 @@ $if(date)$
|
||||||
$endif$
|
$endif$
|
||||||
</info>
|
</info>
|
||||||
$for(include-before)$
|
$for(include-before)$
|
||||||
$include-before$
|
$include-before$
|
||||||
$endfor$
|
$endfor$
|
||||||
$body$
|
$body$
|
||||||
$for(include-after)$
|
$for(include-after)$
|
||||||
$include-after$
|
$include-after$
|
||||||
$endfor$
|
$endfor$
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -411,7 +411,7 @@ library
|
||||||
JuicyPixels >= 3.1.6.1 && < 3.4,
|
JuicyPixels >= 3.1.6.1 && < 3.4,
|
||||||
Glob >= 0.7 && < 0.11,
|
Glob >= 0.7 && < 0.11,
|
||||||
cmark-gfm >= 0.2 && < 0.3,
|
cmark-gfm >= 0.2 && < 0.3,
|
||||||
doctemplates >= 0.3 && < 0.4,
|
doctemplates >= 0.5 && < 0.6,
|
||||||
network-uri >= 2.6 && < 2.7,
|
network-uri >= 2.6 && < 2.7,
|
||||||
network >= 2.6,
|
network >= 2.6,
|
||||||
http-client >= 0.4.30 && < 0.7,
|
http-client >= 0.4.30 && < 0.7,
|
||||||
|
@ -420,6 +420,7 @@ library
|
||||||
case-insensitive >= 1.2 && < 1.3,
|
case-insensitive >= 1.2 && < 1.3,
|
||||||
unicode-transforms >= 0.3 && < 0.4,
|
unicode-transforms >= 0.3 && < 0.4,
|
||||||
HsYAML >= 0.1.1.1 && < 0.2,
|
HsYAML >= 0.1.1.1 && < 0.2,
|
||||||
|
doclayout >= 0.1 && < 0.2,
|
||||||
ipynb >= 0.1 && < 0.2,
|
ipynb >= 0.1 && < 0.2,
|
||||||
attoparsec >= 0.12 && < 0.14
|
attoparsec >= 0.12 && < 0.14
|
||||||
if impl(ghc < 8.0)
|
if impl(ghc < 8.0)
|
||||||
|
@ -465,7 +466,6 @@ library
|
||||||
Text.Pandoc.App,
|
Text.Pandoc.App,
|
||||||
Text.Pandoc.Options,
|
Text.Pandoc.Options,
|
||||||
Text.Pandoc.Extensions,
|
Text.Pandoc.Extensions,
|
||||||
Text.Pandoc.Pretty,
|
|
||||||
Text.Pandoc.Shared,
|
Text.Pandoc.Shared,
|
||||||
Text.Pandoc.MediaBag,
|
Text.Pandoc.MediaBag,
|
||||||
Text.Pandoc.Error,
|
Text.Pandoc.Error,
|
||||||
|
|
|
@ -315,18 +315,14 @@ readFileFromDirs (d:ds) f = catchError
|
||||||
(\_ -> readFileFromDirs ds f)
|
(\_ -> readFileFromDirs ds f)
|
||||||
|
|
||||||
instance TemplateMonad PandocIO where
|
instance TemplateMonad PandocIO where
|
||||||
getPartial fp =
|
getPartial fp = UTF8.toText <$> catchError
|
||||||
lift $ UTF8.toText <$>
|
(readFileStrict fp)
|
||||||
catchError (readFileStrict fp)
|
(\_ -> readDataFile ("templates" </> fp))
|
||||||
(\_ -> readDataFile ("templates" </> fp))
|
|
||||||
|
|
||||||
instance TemplateMonad PandocPure where
|
instance TemplateMonad PandocPure where
|
||||||
getPartial fp =
|
getPartial fp = UTF8.toText <$> catchError
|
||||||
lift $ UTF8.toText <$>
|
(readFileStrict fp)
|
||||||
catchError (readFileStrict fp)
|
(\_ -> readDataFile ("templates" </> fp))
|
||||||
(\_ -> readDataFile ("templates" </> fp))
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
-- | 'CommonState' represents state that is used by all
|
-- | 'CommonState' represents state that is used by all
|
||||||
-- instances of 'PandocMonad'. Normally users should not
|
-- instances of 'PandocMonad'. Normally users should not
|
||||||
|
|
|
@ -46,7 +46,7 @@ import System.Process (readProcessWithExitCode)
|
||||||
import Text.Pandoc.Shared (inDirectory, stringify)
|
import Text.Pandoc.Shared (inDirectory, stringify)
|
||||||
import qualified Text.Pandoc.UTF8 as UTF8
|
import qualified Text.Pandoc.UTF8 as UTF8
|
||||||
import Text.Pandoc.Walk (walkM)
|
import Text.Pandoc.Walk (walkM)
|
||||||
import Text.Pandoc.Writers.Shared (getField, metaToJSON)
|
import Text.Pandoc.Writers.Shared (getField, metaToContext)
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
import Data.List (intercalate)
|
import Data.List (intercalate)
|
||||||
#endif
|
#endif
|
||||||
|
@ -134,22 +134,22 @@ makeWithWkhtmltopdf program pdfargs writer opts doc@(Pandoc meta _) = do
|
||||||
MathJax _ -> ["--run-script", "MathJax.Hub.Register.StartupHook('End Typeset', function() { window.status = 'mathjax_loaded' });",
|
MathJax _ -> ["--run-script", "MathJax.Hub.Register.StartupHook('End Typeset', function() { window.status = 'mathjax_loaded' });",
|
||||||
"--window-status", "mathjax_loaded"]
|
"--window-status", "mathjax_loaded"]
|
||||||
_ -> []
|
_ -> []
|
||||||
meta' <- metaToJSON opts (return . stringify) (return . stringify) meta
|
meta' <- metaToContext opts (return . stringify) (return . stringify) meta
|
||||||
let toArgs (f, mbd) = maybe [] (\d -> ['-':'-':f, d]) mbd
|
let toArgs (f, mbd) = maybe [] (\d -> ['-':'-':f, d]) mbd
|
||||||
let args = pdfargs ++ mathArgs ++ concatMap toArgs
|
let args = pdfargs ++ mathArgs ++ concatMap toArgs
|
||||||
[("page-size", getField "papersize" meta')
|
[("page-size", getField "papersize" meta')
|
||||||
,("title", getField "title" meta')
|
,("title", getField "title" meta')
|
||||||
,("margin-bottom", fromMaybe (Just "1.2in")
|
,("margin-bottom", maybe (Just "1.2in") Just
|
||||||
(getField "margin-bottom" meta'))
|
(getField "margin-bottom" meta'))
|
||||||
,("margin-top", fromMaybe (Just "1.25in")
|
,("margin-top", maybe (Just "1.25in") Just
|
||||||
(getField "margin-top" meta'))
|
(getField "margin-top" meta'))
|
||||||
,("margin-right", fromMaybe (Just "1.25in")
|
,("margin-right", maybe (Just "1.25in") Just
|
||||||
(getField "margin-right" meta'))
|
(getField "margin-right" meta'))
|
||||||
,("margin-left", fromMaybe (Just "1.25in")
|
,("margin-left", maybe (Just "1.25in") Just
|
||||||
(getField "margin-left" meta'))
|
(getField "margin-left" meta'))
|
||||||
,("footer-html", fromMaybe Nothing
|
,("footer-html", maybe Nothing Just
|
||||||
(getField "footer-html" meta'))
|
(getField "footer-html" meta'))
|
||||||
,("header-html", fromMaybe Nothing
|
,("header-html", maybe Nothing Just
|
||||||
(getField "header-html" meta'))
|
(getField "header-html" meta'))
|
||||||
]
|
]
|
||||||
source <- writer opts doc
|
source <- writer opts doc
|
||||||
|
|
|
@ -1,543 +0,0 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
|
||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
|
||||||
{- |
|
|
||||||
Module : Text.Pandoc.Pretty
|
|
||||||
Copyright : Copyright (C) 2010-2019 John MacFarlane
|
|
||||||
License : GNU GPL, version 2 or above
|
|
||||||
|
|
||||||
Maintainer : John MacFarlane <jgm@berkeley.edu>
|
|
||||||
Stability : alpha
|
|
||||||
Portability : portable
|
|
||||||
|
|
||||||
A prettyprinting library for the production of text documents,
|
|
||||||
including wrapped text, indentated blocks, and tables.
|
|
||||||
-}
|
|
||||||
|
|
||||||
module Text.Pandoc.Pretty (
|
|
||||||
Doc
|
|
||||||
, render
|
|
||||||
, cr
|
|
||||||
, blankline
|
|
||||||
, blanklines
|
|
||||||
, space
|
|
||||||
, text
|
|
||||||
, char
|
|
||||||
, prefixed
|
|
||||||
, flush
|
|
||||||
, nest
|
|
||||||
, hang
|
|
||||||
, beforeNonBlank
|
|
||||||
, nowrap
|
|
||||||
, afterBreak
|
|
||||||
, offset
|
|
||||||
, minOffset
|
|
||||||
, height
|
|
||||||
, lblock
|
|
||||||
, cblock
|
|
||||||
, rblock
|
|
||||||
, (<>)
|
|
||||||
, (<+>)
|
|
||||||
, ($$)
|
|
||||||
, ($+$)
|
|
||||||
, isEmpty
|
|
||||||
, empty
|
|
||||||
, cat
|
|
||||||
, hcat
|
|
||||||
, hsep
|
|
||||||
, vcat
|
|
||||||
, vsep
|
|
||||||
, nestle
|
|
||||||
, chomp
|
|
||||||
, inside
|
|
||||||
, braces
|
|
||||||
, brackets
|
|
||||||
, parens
|
|
||||||
, quotes
|
|
||||||
, doubleQuotes
|
|
||||||
, charWidth
|
|
||||||
, realLength
|
|
||||||
)
|
|
||||||
|
|
||||||
where
|
|
||||||
import Prelude
|
|
||||||
import Control.Monad
|
|
||||||
import Control.Monad.State.Strict
|
|
||||||
import Data.Char (isSpace)
|
|
||||||
import Data.Foldable (toList)
|
|
||||||
import Data.List (intersperse, foldl')
|
|
||||||
import Data.Sequence (Seq, ViewL (..), fromList, mapWithIndex, singleton, viewl,
|
|
||||||
(<|))
|
|
||||||
import qualified Data.Sequence as Seq
|
|
||||||
import Data.String
|
|
||||||
|
|
||||||
data RenderState a = RenderState{
|
|
||||||
output :: [a] -- ^ In reverse order
|
|
||||||
, prefix :: String
|
|
||||||
, usePrefix :: Bool
|
|
||||||
, lineLength :: Maybe Int -- ^ 'Nothing' means no wrapping
|
|
||||||
, column :: Int
|
|
||||||
, newlines :: Int -- ^ Number of preceding newlines
|
|
||||||
}
|
|
||||||
|
|
||||||
type DocState a = State (RenderState a) ()
|
|
||||||
|
|
||||||
data D = Text Int String
|
|
||||||
| Block Int [String]
|
|
||||||
| Prefixed String Doc
|
|
||||||
| BeforeNonBlank Doc
|
|
||||||
| Flush Doc
|
|
||||||
| BreakingSpace
|
|
||||||
| AfterBreak String
|
|
||||||
| CarriageReturn
|
|
||||||
| NewLine
|
|
||||||
| BlankLines Int -- number of blank lines
|
|
||||||
deriving (Show, Eq)
|
|
||||||
|
|
||||||
newtype Doc = Doc { unDoc :: Seq D }
|
|
||||||
deriving (Semigroup, Monoid, Show, Eq)
|
|
||||||
|
|
||||||
instance IsString Doc where
|
|
||||||
fromString = text
|
|
||||||
|
|
||||||
isBlank :: D -> Bool
|
|
||||||
isBlank BreakingSpace = True
|
|
||||||
isBlank CarriageReturn = True
|
|
||||||
isBlank NewLine = True
|
|
||||||
isBlank (BlankLines _) = True
|
|
||||||
isBlank (Text _ (c:_)) = isSpace c
|
|
||||||
isBlank _ = False
|
|
||||||
|
|
||||||
-- | True if the document is empty.
|
|
||||||
isEmpty :: Doc -> Bool
|
|
||||||
isEmpty = Seq.null . unDoc
|
|
||||||
|
|
||||||
-- | The empty document.
|
|
||||||
empty :: Doc
|
|
||||||
empty = mempty
|
|
||||||
|
|
||||||
-- | Concatenate a list of 'Doc's.
|
|
||||||
cat :: [Doc] -> Doc
|
|
||||||
cat = mconcat
|
|
||||||
|
|
||||||
-- | Same as 'cat'.
|
|
||||||
hcat :: [Doc] -> Doc
|
|
||||||
hcat = mconcat
|
|
||||||
|
|
||||||
-- | Concatenate a list of 'Doc's, putting breakable spaces
|
|
||||||
-- between them.
|
|
||||||
infixr 6 <+>
|
|
||||||
(<+>) :: Doc -> Doc -> Doc
|
|
||||||
(<+>) x y
|
|
||||||
| isEmpty x = y
|
|
||||||
| isEmpty y = x
|
|
||||||
| otherwise = x <> space <> y
|
|
||||||
|
|
||||||
-- | Same as 'cat', but putting breakable spaces between the
|
|
||||||
-- 'Doc's.
|
|
||||||
hsep :: [Doc] -> Doc
|
|
||||||
hsep = foldr (<+>) empty
|
|
||||||
|
|
||||||
infixr 5 $$
|
|
||||||
-- | @a $$ b@ puts @a@ above @b@.
|
|
||||||
($$) :: Doc -> Doc -> Doc
|
|
||||||
($$) x y
|
|
||||||
| isEmpty x = y
|
|
||||||
| isEmpty y = x
|
|
||||||
| otherwise = x <> cr <> y
|
|
||||||
|
|
||||||
infixr 5 $+$
|
|
||||||
-- | @a $+$ b@ puts @a@ above @b@, with a blank line between.
|
|
||||||
($+$) :: Doc -> Doc -> Doc
|
|
||||||
($+$) x y
|
|
||||||
| isEmpty x = y
|
|
||||||
| isEmpty y = x
|
|
||||||
| otherwise = x <> blankline <> y
|
|
||||||
|
|
||||||
-- | List version of '$$'.
|
|
||||||
vcat :: [Doc] -> Doc
|
|
||||||
vcat = foldr ($$) empty
|
|
||||||
|
|
||||||
-- | List version of '$+$'.
|
|
||||||
vsep :: [Doc] -> Doc
|
|
||||||
vsep = foldr ($+$) empty
|
|
||||||
|
|
||||||
-- | Removes leading blank lines from a 'Doc'.
|
|
||||||
nestle :: Doc -> Doc
|
|
||||||
nestle (Doc d) = Doc $ go d
|
|
||||||
where go x = case viewl x of
|
|
||||||
(BlankLines _ :< rest) -> go rest
|
|
||||||
(NewLine :< rest) -> go rest
|
|
||||||
_ -> x
|
|
||||||
|
|
||||||
-- | Chomps trailing blank space off of a 'Doc'.
|
|
||||||
chomp :: Doc -> Doc
|
|
||||||
chomp d = Doc (fromList dl')
|
|
||||||
where dl = toList (unDoc d)
|
|
||||||
dl' = reverse $ go $ reverse dl
|
|
||||||
go [] = []
|
|
||||||
go (BreakingSpace : xs) = go xs
|
|
||||||
go (CarriageReturn : xs) = go xs
|
|
||||||
go (NewLine : xs) = go xs
|
|
||||||
go (BlankLines _ : xs) = go xs
|
|
||||||
go (Prefixed s d' : xs) = Prefixed s (chomp d') : xs
|
|
||||||
go xs = xs
|
|
||||||
|
|
||||||
outp :: (IsString a) => Int -> String -> DocState a
|
|
||||||
outp off s | off < 0 = do -- offset < 0 means newline characters
|
|
||||||
st' <- get
|
|
||||||
let rawpref = prefix st'
|
|
||||||
when (column st' == 0 && usePrefix st' && not (null rawpref)) $ do
|
|
||||||
let pref = reverse $ dropWhile isSpace $ reverse rawpref
|
|
||||||
modify $ \st -> st{ output = fromString pref : output st
|
|
||||||
, column = column st + realLength pref }
|
|
||||||
let numnewlines = length $ takeWhile (=='\n') $ reverse s
|
|
||||||
modify $ \st -> st { output = fromString s : output st
|
|
||||||
, column = 0
|
|
||||||
, newlines = newlines st + numnewlines }
|
|
||||||
outp off s = do -- offset >= 0 (0 might be combining char)
|
|
||||||
st' <- get
|
|
||||||
let pref = prefix st'
|
|
||||||
when (column st' == 0 && usePrefix st' && not (null pref)) $
|
|
||||||
modify $ \st -> st{ output = fromString pref : output st
|
|
||||||
, column = column st + realLength pref }
|
|
||||||
modify $ \st -> st{ output = fromString s : output st
|
|
||||||
, column = column st + off
|
|
||||||
, newlines = 0 }
|
|
||||||
|
|
||||||
-- | Renders a 'Doc'. @render (Just n)@ will use
|
|
||||||
-- a line length of @n@ to reflow text on breakable spaces.
|
|
||||||
-- @render Nothing@ will not reflow text.
|
|
||||||
render :: (IsString a) => Maybe Int -> Doc -> a
|
|
||||||
render linelen doc = fromString . mconcat . reverse . output $
|
|
||||||
execState (renderDoc doc) startingState
|
|
||||||
where startingState = RenderState{
|
|
||||||
output = mempty
|
|
||||||
, prefix = ""
|
|
||||||
, usePrefix = True
|
|
||||||
, lineLength = linelen
|
|
||||||
, column = 0
|
|
||||||
, newlines = 2 }
|
|
||||||
|
|
||||||
renderDoc :: (IsString a, Monoid a)
|
|
||||||
=> Doc -> DocState a
|
|
||||||
renderDoc = renderList . dropWhile (== BreakingSpace) . toList . unDoc
|
|
||||||
|
|
||||||
data IsBlock = IsBlock Int [String]
|
|
||||||
|
|
||||||
-- This would be nicer with a pattern synonym
|
|
||||||
-- pattern VBlock i s <- mkIsBlock -> Just (IsBlock ..)
|
|
||||||
|
|
||||||
renderList :: (IsString a, Monoid a)
|
|
||||||
=> [D] -> DocState a
|
|
||||||
renderList [] = return ()
|
|
||||||
renderList (Text off s : xs) = do
|
|
||||||
outp off s
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (Prefixed pref d : xs) = do
|
|
||||||
st <- get
|
|
||||||
let oldPref = prefix st
|
|
||||||
put st{ prefix = prefix st ++ pref }
|
|
||||||
renderDoc d
|
|
||||||
modify $ \s -> s{ prefix = oldPref }
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (Flush d : xs) = do
|
|
||||||
st <- get
|
|
||||||
let oldUsePrefix = usePrefix st
|
|
||||||
put st{ usePrefix = False }
|
|
||||||
renderDoc d
|
|
||||||
modify $ \s -> s{ usePrefix = oldUsePrefix }
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (BeforeNonBlank d : xs) =
|
|
||||||
case xs of
|
|
||||||
(x:_) | isBlank x -> renderList xs
|
|
||||||
| otherwise -> renderDoc d >> renderList xs
|
|
||||||
[] -> renderList xs
|
|
||||||
|
|
||||||
renderList [BlankLines _] = return ()
|
|
||||||
|
|
||||||
renderList (BlankLines m : BlankLines n : xs) =
|
|
||||||
renderList (BlankLines (max m n) : xs)
|
|
||||||
|
|
||||||
renderList (BlankLines num : BreakingSpace : xs) =
|
|
||||||
renderList (BlankLines num : xs)
|
|
||||||
|
|
||||||
renderList (BlankLines num : xs) = do
|
|
||||||
st <- get
|
|
||||||
case output st of
|
|
||||||
_ | newlines st > num -> return ()
|
|
||||||
| otherwise -> replicateM_ (1 + num - newlines st) (outp (-1) "\n")
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (CarriageReturn : BlankLines m : xs) =
|
|
||||||
renderList (BlankLines m : xs)
|
|
||||||
|
|
||||||
renderList (CarriageReturn : BreakingSpace : xs) =
|
|
||||||
renderList (CarriageReturn : xs)
|
|
||||||
|
|
||||||
renderList (CarriageReturn : xs) = do
|
|
||||||
st <- get
|
|
||||||
if newlines st > 0 || null xs
|
|
||||||
then renderList xs
|
|
||||||
else do
|
|
||||||
outp (-1) "\n"
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (NewLine : xs) = do
|
|
||||||
outp (-1) "\n"
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (BreakingSpace : CarriageReturn : xs) =
|
|
||||||
renderList (CarriageReturn:xs)
|
|
||||||
renderList (BreakingSpace : NewLine : xs) = renderList (NewLine:xs)
|
|
||||||
renderList (BreakingSpace : BlankLines n : xs) = renderList (BlankLines n:xs)
|
|
||||||
renderList (BreakingSpace : BreakingSpace : xs) = renderList (BreakingSpace:xs)
|
|
||||||
renderList (BreakingSpace : xs) = do
|
|
||||||
let isText (Text _ _) = True
|
|
||||||
isText (Block _ _) = True
|
|
||||||
isText (AfterBreak _) = True
|
|
||||||
isText _ = False
|
|
||||||
let isBreakingSpace BreakingSpace = True
|
|
||||||
isBreakingSpace _ = False
|
|
||||||
let xs' = dropWhile isBreakingSpace xs
|
|
||||||
let next = takeWhile isText xs'
|
|
||||||
st <- get
|
|
||||||
let off = foldl' (+) 0 $ map offsetOf next
|
|
||||||
case lineLength st of
|
|
||||||
Just l | column st + 1 + off > l -> do
|
|
||||||
outp (-1) "\n"
|
|
||||||
renderList xs'
|
|
||||||
_ -> do
|
|
||||||
outp 1 " "
|
|
||||||
renderList xs'
|
|
||||||
|
|
||||||
renderList (AfterBreak s : xs) = do
|
|
||||||
st <- get
|
|
||||||
when (newlines st > 0) $ outp (realLength s) s
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
renderList (Block i1 s1 : Block i2 s2 : xs) =
|
|
||||||
renderList (mergeBlocks False (IsBlock i1 s1) (IsBlock i2 s2) : xs)
|
|
||||||
|
|
||||||
renderList (Block i1 s1 : BreakingSpace : Block i2 s2 : xs) =
|
|
||||||
renderList (mergeBlocks True (IsBlock i1 s1) (IsBlock i2 s2) : xs)
|
|
||||||
|
|
||||||
renderList (Block _width lns : xs) = do
|
|
||||||
st <- get
|
|
||||||
let oldPref = prefix st
|
|
||||||
case column st - realLength oldPref of
|
|
||||||
n | n > 0 -> modify $ \s -> s{ prefix = oldPref ++ replicate n ' ' }
|
|
||||||
_ -> return ()
|
|
||||||
renderList $ intersperse CarriageReturn (map (Text 0) lns)
|
|
||||||
modify $ \s -> s{ prefix = oldPref }
|
|
||||||
renderList xs
|
|
||||||
|
|
||||||
mergeBlocks :: Bool -> IsBlock -> IsBlock -> D
|
|
||||||
mergeBlocks addSpace (IsBlock w1 lns1) (IsBlock w2 lns2) =
|
|
||||||
Block (w1 + w2 + if addSpace then 1 else 0) $
|
|
||||||
zipWith (\l1 l2 -> pad w1 l1 ++ l2) lns1' (map sp lns2')
|
|
||||||
where (lns1', lns2') = case (length lns1, length lns2) of
|
|
||||||
(x, y) | x > y -> (lns1,
|
|
||||||
lns2 ++ replicate (x - y) "")
|
|
||||||
| x < y -> (lns1 ++ replicate (y - x) "",
|
|
||||||
lns2)
|
|
||||||
| otherwise -> (lns1, lns2)
|
|
||||||
pad n s = s ++ replicate (n - realLength s) ' '
|
|
||||||
sp "" = ""
|
|
||||||
sp xs = if addSpace then ' ' : xs else xs
|
|
||||||
|
|
||||||
offsetOf :: D -> Int
|
|
||||||
offsetOf (Text o _) = o
|
|
||||||
offsetOf (Block w _) = w
|
|
||||||
offsetOf BreakingSpace = 1
|
|
||||||
offsetOf _ = 0
|
|
||||||
|
|
||||||
-- | A literal string.
|
|
||||||
text :: String -> Doc
|
|
||||||
text = Doc . toChunks
|
|
||||||
where toChunks :: String -> Seq D
|
|
||||||
toChunks [] = mempty
|
|
||||||
toChunks s = case break (=='\n') s of
|
|
||||||
([], _:ys) -> NewLine <| toChunks ys
|
|
||||||
(xs, _:ys) -> Text (realLength xs) xs <|
|
|
||||||
(NewLine <| toChunks ys)
|
|
||||||
(xs, []) -> singleton $ Text (realLength xs) xs
|
|
||||||
|
|
||||||
-- | A character.
|
|
||||||
char :: Char -> Doc
|
|
||||||
char c = text [c]
|
|
||||||
|
|
||||||
-- | A breaking (reflowable) space.
|
|
||||||
space :: Doc
|
|
||||||
space = Doc $ singleton BreakingSpace
|
|
||||||
|
|
||||||
-- | A carriage return. Does nothing if we're at the beginning of
|
|
||||||
-- a line; otherwise inserts a newline.
|
|
||||||
cr :: Doc
|
|
||||||
cr = Doc $ singleton CarriageReturn
|
|
||||||
|
|
||||||
-- | Inserts a blank line unless one exists already.
|
|
||||||
-- (@blankline <> blankline@ has the same effect as @blankline@.
|
|
||||||
blankline :: Doc
|
|
||||||
blankline = Doc $ singleton (BlankLines 1)
|
|
||||||
|
|
||||||
-- | Inserts blank lines unless they exist already.
|
|
||||||
-- (@blanklines m <> blanklines n@ has the same effect as @blanklines (max m n)@.
|
|
||||||
blanklines :: Int -> Doc
|
|
||||||
blanklines n = Doc $ singleton (BlankLines n)
|
|
||||||
|
|
||||||
-- | Uses the specified string as a prefix for every line of
|
|
||||||
-- the inside document (except the first, if not at the beginning
|
|
||||||
-- of the line).
|
|
||||||
prefixed :: String -> Doc -> Doc
|
|
||||||
prefixed pref doc = Doc $ singleton $ Prefixed pref doc
|
|
||||||
|
|
||||||
-- | Makes a 'Doc' flush against the left margin.
|
|
||||||
flush :: Doc -> Doc
|
|
||||||
flush doc = Doc $ singleton $ Flush doc
|
|
||||||
|
|
||||||
-- | Indents a 'Doc' by the specified number of spaces.
|
|
||||||
nest :: Int -> Doc -> Doc
|
|
||||||
nest ind = prefixed (replicate ind ' ')
|
|
||||||
|
|
||||||
-- | A hanging indent. @hang ind start doc@ prints @start@,
|
|
||||||
-- then @doc@, leaving an indent of @ind@ spaces on every
|
|
||||||
-- line but the first.
|
|
||||||
hang :: Int -> Doc -> Doc -> Doc
|
|
||||||
hang ind start doc = start <> nest ind doc
|
|
||||||
|
|
||||||
-- | @beforeNonBlank d@ conditionally includes @d@ unless it is
|
|
||||||
-- followed by blank space.
|
|
||||||
beforeNonBlank :: Doc -> Doc
|
|
||||||
beforeNonBlank d = Doc $ singleton (BeforeNonBlank d)
|
|
||||||
|
|
||||||
-- | Makes a 'Doc' non-reflowable.
|
|
||||||
nowrap :: Doc -> Doc
|
|
||||||
nowrap doc = Doc $ mapWithIndex replaceSpace $ unDoc doc
|
|
||||||
where replaceSpace _ BreakingSpace = Text 1 " "
|
|
||||||
replaceSpace _ x = x
|
|
||||||
|
|
||||||
-- | Content to print only if it comes at the beginning of a line,
|
|
||||||
-- to be used e.g. for escaping line-initial `.` in roff man.
|
|
||||||
afterBreak :: String -> Doc
|
|
||||||
afterBreak s = Doc $ singleton (AfterBreak s)
|
|
||||||
|
|
||||||
-- | Returns the width of a 'Doc'.
|
|
||||||
offset :: Doc -> Int
|
|
||||||
offset d = maximum (0: map realLength (lines $ render Nothing d))
|
|
||||||
|
|
||||||
-- | Returns the minimal width of a 'Doc' when reflowed at breakable spaces.
|
|
||||||
minOffset :: Doc -> Int
|
|
||||||
minOffset d = maximum (0: map realLength (lines $ render (Just 0) d))
|
|
||||||
|
|
||||||
-- | @lblock n d@ is a block of width @n@ characters, with
|
|
||||||
-- text derived from @d@ and aligned to the left.
|
|
||||||
lblock :: Int -> Doc -> Doc
|
|
||||||
lblock = block id
|
|
||||||
|
|
||||||
-- | Like 'lblock' but aligned to the right.
|
|
||||||
rblock :: Int -> Doc -> Doc
|
|
||||||
rblock w = block (\s -> replicate (w - realLength s) ' ' ++ s) w
|
|
||||||
|
|
||||||
-- | Like 'lblock' but aligned centered.
|
|
||||||
cblock :: Int -> Doc -> Doc
|
|
||||||
cblock w = block (\s -> replicate ((w - realLength s) `div` 2) ' ' ++ s) w
|
|
||||||
|
|
||||||
-- | Returns the height of a block or other 'Doc'.
|
|
||||||
height :: Doc -> Int
|
|
||||||
height = length . lines . render Nothing
|
|
||||||
|
|
||||||
block :: (String -> String) -> Int -> Doc -> Doc
|
|
||||||
block filler width d
|
|
||||||
| width < 1 && not (isEmpty d) = block filler 1 d
|
|
||||||
| otherwise = Doc $ singleton $ Block width $ map filler
|
|
||||||
$ chop width $ render (Just width) d
|
|
||||||
|
|
||||||
chop :: Int -> String -> [String]
|
|
||||||
chop _ [] = []
|
|
||||||
chop n cs = case break (=='\n') cs of
|
|
||||||
(xs, ys) -> if len <= n
|
|
||||||
then case ys of
|
|
||||||
[] -> [xs]
|
|
||||||
['\n'] -> [xs]
|
|
||||||
(_:zs) -> xs : chop n zs
|
|
||||||
else take n xs : chop n (drop n xs ++ ys)
|
|
||||||
where len = realLength xs
|
|
||||||
|
|
||||||
-- | Encloses a 'Doc' inside a start and end 'Doc'.
|
|
||||||
inside :: Doc -> Doc -> Doc -> Doc
|
|
||||||
inside start end contents =
|
|
||||||
start <> contents <> end
|
|
||||||
|
|
||||||
-- | Puts a 'Doc' in curly braces.
|
|
||||||
braces :: Doc -> Doc
|
|
||||||
braces = inside (char '{') (char '}')
|
|
||||||
|
|
||||||
-- | Puts a 'Doc' in square brackets.
|
|
||||||
brackets :: Doc -> Doc
|
|
||||||
brackets = inside (char '[') (char ']')
|
|
||||||
|
|
||||||
-- | Puts a 'Doc' in parentheses.
|
|
||||||
parens :: Doc -> Doc
|
|
||||||
parens = inside (char '(') (char ')')
|
|
||||||
|
|
||||||
-- | Wraps a 'Doc' in single quotes.
|
|
||||||
quotes :: Doc -> Doc
|
|
||||||
quotes = inside (char '\'') (char '\'')
|
|
||||||
|
|
||||||
-- | Wraps a 'Doc' in double quotes.
|
|
||||||
doubleQuotes :: Doc -> Doc
|
|
||||||
doubleQuotes = inside (char '"') (char '"')
|
|
||||||
|
|
||||||
-- | Returns width of a character in a monospace font: 0 for a combining
|
|
||||||
-- character, 1 for a regular character, 2 for an East Asian wide character.
|
|
||||||
charWidth :: Char -> Int
|
|
||||||
charWidth c =
|
|
||||||
case c of
|
|
||||||
_ | c < '\x0300' -> 1
|
|
||||||
| c >= '\x0300' && c <= '\x036F' -> 0 -- combining
|
|
||||||
| c >= '\x0370' && c <= '\x10FC' -> 1
|
|
||||||
| c >= '\x1100' && c <= '\x115F' -> 2
|
|
||||||
| c >= '\x1160' && c <= '\x11A2' -> 1
|
|
||||||
| c >= '\x11A3' && c <= '\x11A7' -> 2
|
|
||||||
| c >= '\x11A8' && c <= '\x11F9' -> 1
|
|
||||||
| c >= '\x11FA' && c <= '\x11FF' -> 2
|
|
||||||
| c >= '\x1200' && c <= '\x2328' -> 1
|
|
||||||
| c >= '\x2329' && c <= '\x232A' -> 2
|
|
||||||
| c >= '\x232B' && c <= '\x2E31' -> 1
|
|
||||||
| c >= '\x2E80' && c <= '\x303E' -> 2
|
|
||||||
| c == '\x303F' -> 1
|
|
||||||
| c >= '\x3041' && c <= '\x3247' -> 2
|
|
||||||
| c >= '\x3248' && c <= '\x324F' -> 1 -- ambiguous
|
|
||||||
| c >= '\x3250' && c <= '\x4DBF' -> 2
|
|
||||||
| c >= '\x4DC0' && c <= '\x4DFF' -> 1
|
|
||||||
| c >= '\x4E00' && c <= '\xA4C6' -> 2
|
|
||||||
| c >= '\xA4D0' && c <= '\xA95F' -> 1
|
|
||||||
| c >= '\xA960' && c <= '\xA97C' -> 2
|
|
||||||
| c >= '\xA980' && c <= '\xABF9' -> 1
|
|
||||||
| c >= '\xAC00' && c <= '\xD7FB' -> 2
|
|
||||||
| c >= '\xD800' && c <= '\xDFFF' -> 1
|
|
||||||
| c >= '\xE000' && c <= '\xF8FF' -> 1 -- ambiguous
|
|
||||||
| c >= '\xF900' && c <= '\xFAFF' -> 2
|
|
||||||
| c >= '\xFB00' && c <= '\xFDFD' -> 1
|
|
||||||
| c >= '\xFE00' && c <= '\xFE0F' -> 1 -- ambiguous
|
|
||||||
| c >= '\xFE10' && c <= '\xFE19' -> 2
|
|
||||||
| c >= '\xFE20' && c <= '\xFE26' -> 1
|
|
||||||
| c >= '\xFE30' && c <= '\xFE6B' -> 2
|
|
||||||
| c >= '\xFE70' && c <= '\xFEFF' -> 1
|
|
||||||
| c >= '\xFF01' && c <= '\xFF60' -> 2
|
|
||||||
| c >= '\xFF61' && c <= '\x16A38' -> 1
|
|
||||||
| c >= '\x1B000' && c <= '\x1B001' -> 2
|
|
||||||
| c >= '\x1D000' && c <= '\x1F1FF' -> 1
|
|
||||||
| c >= '\x1F200' && c <= '\x1F251' -> 2
|
|
||||||
| c >= '\x1F300' && c <= '\x1F773' -> 1
|
|
||||||
| c >= '\x20000' && c <= '\x3FFFD' -> 2
|
|
||||||
| otherwise -> 1
|
|
||||||
|
|
||||||
-- | Get real length of string, taking into account combining and double-wide
|
|
||||||
-- characters.
|
|
||||||
realLength :: String -> Int
|
|
||||||
realLength = foldl' (+) 0 . map charWidth
|
|
|
@ -128,7 +128,7 @@ import Text.Pandoc.Asciify (toAsciiChar)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Extensions (Extensions, Extension(..), extensionEnabled)
|
import Text.Pandoc.Extensions (Extensions, Extension(..), extensionEnabled)
|
||||||
import Text.Pandoc.Generic (bottomUp)
|
import Text.Pandoc.Generic (bottomUp)
|
||||||
import Text.Pandoc.Pretty (charWidth)
|
import Text.DocLayout (charWidth)
|
||||||
import Text.Pandoc.Walk
|
import Text.Pandoc.Walk
|
||||||
|
|
||||||
-- | Version number of pandoc library.
|
-- | Version number of pandoc library.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{- |
|
{- |
|
||||||
Module : Text.Pandoc.Templates
|
Module : Text.Pandoc.Templates
|
||||||
|
@ -8,8 +10,7 @@
|
||||||
Stability : alpha
|
Stability : alpha
|
||||||
Portability : portable
|
Portability : portable
|
||||||
|
|
||||||
A simple templating system with variable substitution and conditionals.
|
Utility functions for working with pandoc templates.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module Text.Pandoc.Templates ( Template
|
module Text.Pandoc.Templates ( Template
|
||||||
|
@ -52,3 +53,5 @@ getDefaultTemplate writer = do
|
||||||
_ -> do
|
_ -> do
|
||||||
let fname = "templates" </> "default" <.> format
|
let fname = "templates" </> "default" <.> format
|
||||||
UTF8.toText <$> readDataFile fname
|
UTF8.toText <$> readDataFile fname
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import Data.Char (isPunctuation, isSpace, toLower, toUpper)
|
||||||
import Data.List (intercalate, intersperse, stripPrefix)
|
import Data.List (intercalate, intersperse, stripPrefix)
|
||||||
import Data.Maybe (fromMaybe, isJust, listToMaybe)
|
import Data.Maybe (fromMaybe, isJust, listToMaybe)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Text as T
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
|
@ -33,7 +34,7 @@ import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Parsing hiding (blankline, space)
|
import Text.Pandoc.Parsing hiding (blankline, space)
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -79,14 +80,11 @@ pandocToAsciiDoc opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext opts
|
||||||
render' = render colwidth
|
(blockListToAsciiDoc opts)
|
||||||
metadata <- metaToJSON opts
|
(fmap chomp . inlineListToAsciiDoc opts)
|
||||||
(fmap render' . blockListToAsciiDoc opts)
|
|
||||||
(fmap render' . inlineListToAsciiDoc opts)
|
|
||||||
meta
|
meta
|
||||||
body <- vcat <$> mapM (elementToAsciiDoc 1 opts) (hierarchicalize blocks)
|
main <- vcat <$> mapM (elementToAsciiDoc 1 opts) (hierarchicalize blocks)
|
||||||
let main = render colwidth body
|
|
||||||
st <- get
|
st <- get
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "toc"
|
$ defField "toc"
|
||||||
|
@ -94,13 +92,13 @@ pandocToAsciiDoc opts (Pandoc meta blocks) = do
|
||||||
isJust (writerTemplate opts))
|
isJust (writerTemplate opts))
|
||||||
$ defField "math" (hasMath st)
|
$ defField "math" (hasMath st)
|
||||||
$ defField "titleblock" titleblock metadata
|
$ defField "titleblock" titleblock metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
elementToAsciiDoc :: PandocMonad m
|
elementToAsciiDoc :: PandocMonad m
|
||||||
=> Int -> WriterOptions -> Element -> ADW m Doc
|
=> Int -> WriterOptions -> Element -> ADW m (Doc Text)
|
||||||
elementToAsciiDoc _ opts (Blk b) = blockToAsciiDoc opts b
|
elementToAsciiDoc _ opts (Blk b) = blockToAsciiDoc opts b
|
||||||
elementToAsciiDoc nestlevel opts (Sec _lvl _num attr label children) = do
|
elementToAsciiDoc nestlevel opts (Sec _lvl _num attr label children) = do
|
||||||
hdr <- blockToAsciiDoc opts (Header nestlevel attr label)
|
hdr <- blockToAsciiDoc opts (Header nestlevel attr label)
|
||||||
|
@ -137,7 +135,7 @@ needsEscaping s = beginsWithOrderedListMarker s || isBracketed s
|
||||||
blockToAsciiDoc :: PandocMonad m
|
blockToAsciiDoc :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> ADW m Doc
|
-> ADW m (Doc Text)
|
||||||
blockToAsciiDoc _ Null = return empty
|
blockToAsciiDoc _ Null = return empty
|
||||||
blockToAsciiDoc opts (Plain inlines) = do
|
blockToAsciiDoc opts (Plain inlines) = do
|
||||||
contents <- inlineListToAsciiDoc opts inlines
|
contents <- inlineListToAsciiDoc opts inlines
|
||||||
|
@ -147,7 +145,7 @@ blockToAsciiDoc opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) =
|
||||||
blockToAsciiDoc opts (Para inlines) = do
|
blockToAsciiDoc opts (Para inlines) = do
|
||||||
contents <- inlineListToAsciiDoc opts inlines
|
contents <- inlineListToAsciiDoc opts inlines
|
||||||
-- escape if para starts with ordered list marker
|
-- escape if para starts with ordered list marker
|
||||||
let esc = if needsEscaping (render Nothing contents)
|
let esc = if needsEscaping (T.unpack $ render Nothing contents)
|
||||||
then text "{empty}"
|
then text "{empty}"
|
||||||
else empty
|
else empty
|
||||||
return $ esc <> contents <> blankline
|
return $ esc <> contents <> blankline
|
||||||
|
@ -257,7 +255,7 @@ blockToAsciiDoc opts (BulletList items) = do
|
||||||
modify $ \st -> st{ inList = True }
|
modify $ \st -> st{ inList = True }
|
||||||
contents <- mapM (bulletListItemToAsciiDoc opts) items
|
contents <- mapM (bulletListItemToAsciiDoc opts) items
|
||||||
modify $ \st -> st{ inList = inlist }
|
modify $ \st -> st{ inList = inlist }
|
||||||
return $ cat contents <> blankline
|
return $ mconcat contents <> blankline
|
||||||
blockToAsciiDoc opts (OrderedList (start, sty, _delim) items) = do
|
blockToAsciiDoc opts (OrderedList (start, sty, _delim) items) = do
|
||||||
let listStyle = case sty of
|
let listStyle = case sty of
|
||||||
DefaultStyle -> []
|
DefaultStyle -> []
|
||||||
|
@ -272,13 +270,13 @@ blockToAsciiDoc opts (OrderedList (start, sty, _delim) items) = do
|
||||||
modify $ \st -> st{ inList = True }
|
modify $ \st -> st{ inList = True }
|
||||||
contents <- mapM (orderedListItemToAsciiDoc opts) items
|
contents <- mapM (orderedListItemToAsciiDoc opts) items
|
||||||
modify $ \st -> st{ inList = inlist }
|
modify $ \st -> st{ inList = inlist }
|
||||||
return $ listoptions $$ cat contents <> blankline
|
return $ listoptions $$ mconcat contents <> blankline
|
||||||
blockToAsciiDoc opts (DefinitionList items) = do
|
blockToAsciiDoc opts (DefinitionList items) = do
|
||||||
inlist <- gets inList
|
inlist <- gets inList
|
||||||
modify $ \st -> st{ inList = True }
|
modify $ \st -> st{ inList = True }
|
||||||
contents <- mapM (definitionListItemToAsciiDoc opts) items
|
contents <- mapM (definitionListItemToAsciiDoc opts) items
|
||||||
modify $ \st -> st{ inList = inlist }
|
modify $ \st -> st{ inList = inlist }
|
||||||
return $ cat contents <> blankline
|
return $ mconcat contents <> blankline
|
||||||
blockToAsciiDoc opts (Div (ident,classes,_) bs) = do
|
blockToAsciiDoc opts (Div (ident,classes,_) bs) = do
|
||||||
let identifier = if null ident then empty else "[[" <> text ident <> "]]"
|
let identifier = if null ident then empty else "[[" <> text ident <> "]]"
|
||||||
let admonitions = ["attention","caution","danger","error","hint",
|
let admonitions = ["attention","caution","danger","error","hint",
|
||||||
|
@ -305,7 +303,7 @@ blockToAsciiDoc opts (Div (ident,classes,_) bs) = do
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to asciidoc.
|
-- | Convert bullet list item (list of blocks) to asciidoc.
|
||||||
bulletListItemToAsciiDoc :: PandocMonad m
|
bulletListItemToAsciiDoc :: PandocMonad m
|
||||||
=> WriterOptions -> [Block] -> ADW m Doc
|
=> WriterOptions -> [Block] -> ADW m (Doc Text)
|
||||||
bulletListItemToAsciiDoc opts blocks = do
|
bulletListItemToAsciiDoc opts blocks = do
|
||||||
lev <- gets bulletListLevel
|
lev <- gets bulletListLevel
|
||||||
modify $ \s -> s{ bulletListLevel = lev + 1 }
|
modify $ \s -> s{ bulletListLevel = lev + 1 }
|
||||||
|
@ -315,7 +313,8 @@ bulletListItemToAsciiDoc opts blocks = do
|
||||||
return $ marker <> text " " <> listBegin blocks <>
|
return $ marker <> text " " <> listBegin blocks <>
|
||||||
contents <> cr
|
contents <> cr
|
||||||
|
|
||||||
addBlock :: PandocMonad m => WriterOptions -> Doc -> Block -> ADW m Doc
|
addBlock :: PandocMonad m
|
||||||
|
=> WriterOptions -> Doc Text -> Block -> ADW m (Doc Text)
|
||||||
addBlock opts d b = do
|
addBlock opts d b = do
|
||||||
x <- chomp <$> blockToAsciiDoc opts b
|
x <- chomp <$> blockToAsciiDoc opts b
|
||||||
return $
|
return $
|
||||||
|
@ -328,7 +327,7 @@ addBlock opts d b = do
|
||||||
Plain{} | isEmpty d -> x
|
Plain{} | isEmpty d -> x
|
||||||
_ -> d <> cr <> text "+" <> cr <> x
|
_ -> d <> cr <> text "+" <> cr <> x
|
||||||
|
|
||||||
listBegin :: [Block] -> Doc
|
listBegin :: [Block] -> Doc Text
|
||||||
listBegin blocks =
|
listBegin blocks =
|
||||||
case blocks of
|
case blocks of
|
||||||
Para (Math DisplayMath _:_) : _ -> "{blank}"
|
Para (Math DisplayMath _:_) : _ -> "{blank}"
|
||||||
|
@ -342,7 +341,7 @@ listBegin blocks =
|
||||||
orderedListItemToAsciiDoc :: PandocMonad m
|
orderedListItemToAsciiDoc :: PandocMonad m
|
||||||
=> WriterOptions -- ^ options
|
=> WriterOptions -- ^ options
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> ADW m Doc
|
-> ADW m (Doc Text)
|
||||||
orderedListItemToAsciiDoc opts blocks = do
|
orderedListItemToAsciiDoc opts blocks = do
|
||||||
lev <- gets orderedListLevel
|
lev <- gets orderedListLevel
|
||||||
modify $ \s -> s{ orderedListLevel = lev + 1 }
|
modify $ \s -> s{ orderedListLevel = lev + 1 }
|
||||||
|
@ -355,7 +354,7 @@ orderedListItemToAsciiDoc opts blocks = do
|
||||||
definitionListItemToAsciiDoc :: PandocMonad m
|
definitionListItemToAsciiDoc :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Inline],[[Block]])
|
-> ([Inline],[[Block]])
|
||||||
-> ADW m Doc
|
-> ADW m (Doc Text)
|
||||||
definitionListItemToAsciiDoc opts (label, defs) = do
|
definitionListItemToAsciiDoc opts (label, defs) = do
|
||||||
labelText <- inlineListToAsciiDoc opts label
|
labelText <- inlineListToAsciiDoc opts label
|
||||||
marker <- gets defListMarker
|
marker <- gets defListMarker
|
||||||
|
@ -363,7 +362,7 @@ definitionListItemToAsciiDoc opts (label, defs) = do
|
||||||
then modify (\st -> st{ defListMarker = ";;"})
|
then modify (\st -> st{ defListMarker = ";;"})
|
||||||
else modify (\st -> st{ defListMarker = "::"})
|
else modify (\st -> st{ defListMarker = "::"})
|
||||||
let divider = cr <> text "+" <> cr
|
let divider = cr <> text "+" <> cr
|
||||||
let defsToAsciiDoc :: PandocMonad m => [Block] -> ADW m Doc
|
let defsToAsciiDoc :: PandocMonad m => [Block] -> ADW m (Doc Text)
|
||||||
defsToAsciiDoc ds = (vcat . intersperse divider . map chomp)
|
defsToAsciiDoc ds = (vcat . intersperse divider . map chomp)
|
||||||
`fmap` mapM (blockToAsciiDoc opts) ds
|
`fmap` mapM (blockToAsciiDoc opts) ds
|
||||||
defs' <- mapM defsToAsciiDoc defs
|
defs' <- mapM defsToAsciiDoc defs
|
||||||
|
@ -375,13 +374,14 @@ definitionListItemToAsciiDoc opts (label, defs) = do
|
||||||
blockListToAsciiDoc :: PandocMonad m
|
blockListToAsciiDoc :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> ADW m Doc
|
-> ADW m (Doc Text)
|
||||||
blockListToAsciiDoc opts blocks = cat `fmap` mapM (blockToAsciiDoc opts) blocks
|
blockListToAsciiDoc opts blocks =
|
||||||
|
mconcat `fmap` mapM (blockToAsciiDoc opts) blocks
|
||||||
|
|
||||||
data SpacyLocation = End | Start
|
data SpacyLocation = End | Start
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to asciidoc.
|
-- | Convert list of Pandoc inline elements to asciidoc.
|
||||||
inlineListToAsciiDoc :: PandocMonad m => WriterOptions -> [Inline] -> ADW m Doc
|
inlineListToAsciiDoc :: PandocMonad m => WriterOptions -> [Inline] -> ADW m (Doc Text)
|
||||||
inlineListToAsciiDoc opts lst = do
|
inlineListToAsciiDoc opts lst = do
|
||||||
oldIntraword <- gets intraword
|
oldIntraword <- gets intraword
|
||||||
setIntraword False
|
setIntraword False
|
||||||
|
@ -424,7 +424,7 @@ withIntraword :: PandocMonad m => ADW m a -> ADW m a
|
||||||
withIntraword p = setIntraword True *> p <* setIntraword False
|
withIntraword p = setIntraword True *> p <* setIntraword False
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to asciidoc.
|
-- | Convert Pandoc inline element to asciidoc.
|
||||||
inlineToAsciiDoc :: PandocMonad m => WriterOptions -> Inline -> ADW m Doc
|
inlineToAsciiDoc :: PandocMonad m => WriterOptions -> Inline -> ADW m (Doc Text)
|
||||||
inlineToAsciiDoc opts (Emph [Strong xs]) =
|
inlineToAsciiDoc opts (Emph [Strong xs]) =
|
||||||
inlineToAsciiDoc opts (Strong [Emph xs]) -- see #5565
|
inlineToAsciiDoc opts (Strong [Emph xs]) -- see #5565
|
||||||
inlineToAsciiDoc opts (Emph lst) = do
|
inlineToAsciiDoc opts (Emph lst) = do
|
||||||
|
@ -529,7 +529,7 @@ inlineToAsciiDoc opts (Image attr alternate (src, tit)) = do
|
||||||
dimList = showDim Width ++ showDim Height
|
dimList = showDim Width ++ showDim Height
|
||||||
dims = if null dimList
|
dims = if null dimList
|
||||||
then empty
|
then empty
|
||||||
else "," <> cat (intersperse "," dimList)
|
else "," <> mconcat (intersperse "," dimList)
|
||||||
return $ "image:" <> text src <> "[" <> linktext <> linktitle <> dims <> "]"
|
return $ "image:" <> text src <> "[" <> linktext <> linktitle <> dims <> "]"
|
||||||
inlineToAsciiDoc opts (Note [Para inlines]) =
|
inlineToAsciiDoc opts (Note [Para inlines]) =
|
||||||
inlineToAsciiDoc opts (Note [Plain inlines])
|
inlineToAsciiDoc opts (Note [Plain inlines])
|
||||||
|
|
|
@ -49,9 +49,9 @@ writeCommonMark opts (Pandoc meta blocks) = do
|
||||||
then []
|
then []
|
||||||
else [OrderedList (1, Decimal, Period) $ reverse notes]
|
else [OrderedList (1, Decimal, Period) $ reverse notes]
|
||||||
main <- blocksToCommonMark opts (blocks' ++ notes')
|
main <- blocksToCommonMark opts (blocks' ++ notes')
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(blocksToCommonMark opts)
|
(fmap T.stripEnd . blocksToCommonMark opts)
|
||||||
(inlinesToCommonMark opts)
|
(fmap T.stripEnd . inlinesToCommonMark opts)
|
||||||
meta
|
meta
|
||||||
let context =
|
let context =
|
||||||
-- for backwards compatibility we populate toc
|
-- for backwards compatibility we populate toc
|
||||||
|
|
|
@ -19,6 +19,7 @@ import Data.Char (ord, isDigit, toLower)
|
||||||
import Data.List (intercalate, intersperse)
|
import Data.List (intercalate, intersperse)
|
||||||
import Data.Maybe (mapMaybe)
|
import Data.Maybe (mapMaybe)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
import Network.URI (unEscapeString)
|
import Network.URI (unEscapeString)
|
||||||
import Text.Pandoc.BCP47
|
import Text.Pandoc.BCP47
|
||||||
import Text.Pandoc.Class (PandocMonad, report, toLang)
|
import Text.Pandoc.Class (PandocMonad, report, toLang)
|
||||||
|
@ -26,7 +27,7 @@ import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Walk (query)
|
import Text.Pandoc.Walk (query)
|
||||||
|
@ -60,16 +61,15 @@ pandocToConTeXt options (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText options == WrapAuto
|
let colwidth = if writerWrapText options == WrapAuto
|
||||||
then Just $ writerColumns options
|
then Just $ writerColumns options
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext options
|
||||||
render' = render colwidth
|
blockListToConTeXt
|
||||||
metadata <- metaToJSON options
|
(fmap chomp . inlineListToConTeXt)
|
||||||
(fmap render' . blockListToConTeXt)
|
|
||||||
(fmap render' . inlineListToConTeXt)
|
|
||||||
meta
|
meta
|
||||||
body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
|
body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
|
||||||
let main = (render' . vcat) body
|
let main = vcat body
|
||||||
let layoutFromMargins = intercalate [','] $ mapMaybe (\(x,y) ->
|
let layoutFromMargins = mconcat $ intersperse ("," :: Doc Text) $
|
||||||
((x ++ "=") ++) <$> getField y metadata)
|
mapMaybe (\(x,y) ->
|
||||||
|
((x <> "=") <>) <$> getField y metadata)
|
||||||
[("leftmargin","margin-left")
|
[("leftmargin","margin-left")
|
||||||
,("rightmargin","margin-right")
|
,("rightmargin","margin-right")
|
||||||
,("top","margin-top")
|
,("top","margin-top")
|
||||||
|
@ -77,7 +77,8 @@ pandocToConTeXt options (Pandoc meta blocks) = do
|
||||||
]
|
]
|
||||||
mblang <- fromBCP47 (getLang options meta)
|
mblang <- fromBCP47 (getLang options meta)
|
||||||
let context = defField "toc" (writerTableOfContents options)
|
let context = defField "toc" (writerTableOfContents options)
|
||||||
$ defField "placelist" (intercalate ("," :: String) $
|
$ defField "placelist"
|
||||||
|
(mconcat . intersperse ("," :: Doc Text) $
|
||||||
take (writerTOCDepth options +
|
take (writerTOCDepth options +
|
||||||
case writerTopLevelDivision options of
|
case writerTopLevelDivision options of
|
||||||
TopLevelPart -> 0
|
TopLevelPart -> 0
|
||||||
|
@ -88,26 +89,30 @@ pandocToConTeXt options (Pandoc meta blocks) = do
|
||||||
$ defField "body" main
|
$ defField "body" main
|
||||||
$ defField "layout" layoutFromMargins
|
$ defField "layout" layoutFromMargins
|
||||||
$ defField "number-sections" (writerNumberSections options)
|
$ defField "number-sections" (writerNumberSections options)
|
||||||
$ maybe id (defField "context-lang") mblang
|
$ maybe id (\l ->
|
||||||
$ (case getField "papersize" metadata of
|
defField "context-lang" (text l :: Doc Text)) mblang
|
||||||
|
$ (case T.unpack . render Nothing <$>
|
||||||
|
getField "papersize" metadata of
|
||||||
Just (('a':d:ds) :: String)
|
Just (('a':d:ds) :: String)
|
||||||
| all isDigit (d:ds) -> resetField "papersize"
|
| all isDigit (d:ds) -> resetField "papersize"
|
||||||
(('A':d:ds) :: String)
|
(T.pack ('A':d:ds))
|
||||||
_ -> id)
|
_ -> id)
|
||||||
$ (case toLower <$> lookupMetaString "pdfa" meta of
|
$ (case toLower <$> lookupMetaString "pdfa" meta of
|
||||||
"true" -> resetField "pdfa" ("1b:2005" :: String)
|
"true" -> resetField "pdfa" (T.pack "1b:2005")
|
||||||
_ -> id) metadata
|
_ -> id) metadata
|
||||||
let context' = defField "context-dir" (toContextDir
|
let context' = defField "context-dir" (maybe mempty toContextDir
|
||||||
$ getField "dir" context) context
|
$ getField "dir" context) context
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate options of
|
case writerTemplate options of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context'
|
Just tpl -> renderTemplate tpl context'
|
||||||
|
|
||||||
toContextDir :: Maybe String -> String
|
-- change rtl to r2l, ltr to l2r
|
||||||
toContextDir (Just "rtl") = "r2l"
|
toContextDir :: Doc Text -> Doc Text
|
||||||
toContextDir (Just "ltr") = "l2r"
|
toContextDir = fmap (\t -> case t of
|
||||||
toContextDir _ = ""
|
"ltr" -> "l2r"
|
||||||
|
"rtl" -> "r2l"
|
||||||
|
_ -> t)
|
||||||
|
|
||||||
-- | escape things as needed for ConTeXt
|
-- | escape things as needed for ConTeXt
|
||||||
escapeCharForConTeXt :: WriterOptions -> Char -> String
|
escapeCharForConTeXt :: WriterOptions -> Char -> String
|
||||||
|
@ -143,7 +148,7 @@ toLabel z = concatMap go z
|
||||||
| otherwise = [x]
|
| otherwise = [x]
|
||||||
|
|
||||||
-- | Convert Elements to ConTeXt
|
-- | Convert Elements to ConTeXt
|
||||||
elementToConTeXt :: PandocMonad m => WriterOptions -> Element -> WM m Doc
|
elementToConTeXt :: PandocMonad m => WriterOptions -> Element -> WM m (Doc Text)
|
||||||
elementToConTeXt _ (Blk block) = blockToConTeXt block
|
elementToConTeXt _ (Blk block) = blockToConTeXt block
|
||||||
elementToConTeXt opts (Sec level _ attr title' elements) = do
|
elementToConTeXt opts (Sec level _ attr title' elements) = do
|
||||||
header' <- sectionHeader attr level title'
|
header' <- sectionHeader attr level title'
|
||||||
|
@ -152,7 +157,7 @@ elementToConTeXt opts (Sec level _ attr title' elements) = do
|
||||||
return $ header' $$ vcat innerContents $$ footer'
|
return $ header' $$ vcat innerContents $$ footer'
|
||||||
|
|
||||||
-- | Convert Pandoc block element to ConTeXt.
|
-- | Convert Pandoc block element to ConTeXt.
|
||||||
blockToConTeXt :: PandocMonad m => Block -> WM m Doc
|
blockToConTeXt :: PandocMonad m => Block -> WM m (Doc Text)
|
||||||
blockToConTeXt Null = return empty
|
blockToConTeXt Null = return empty
|
||||||
blockToConTeXt (Plain lst) = inlineListToConTeXt lst
|
blockToConTeXt (Plain lst) = inlineListToConTeXt lst
|
||||||
-- title beginning with fig: indicates that the image is a figure
|
-- title beginning with fig: indicates that the image is a figure
|
||||||
|
@ -258,7 +263,8 @@ blockToConTeXt (Table caption aligns widths heads rows) = do
|
||||||
else "title=" <> braces captionText
|
else "title=" <> braces captionText
|
||||||
) $$ body $$ "\\stopplacetable" <> blankline
|
) $$ body $$ "\\stopplacetable" <> blankline
|
||||||
|
|
||||||
tableToConTeXt :: PandocMonad m => Tabl -> Doc -> [Doc] -> WM m Doc
|
tableToConTeXt :: PandocMonad m
|
||||||
|
=> Tabl -> Doc Text -> [Doc Text] -> WM m (Doc Text)
|
||||||
tableToConTeXt Xtb heads rows =
|
tableToConTeXt Xtb heads rows =
|
||||||
return $ "\\startxtable" $$
|
return $ "\\startxtable" $$
|
||||||
(if isEmpty heads
|
(if isEmpty heads
|
||||||
|
@ -280,7 +286,7 @@ tableToConTeXt Ntb heads rows =
|
||||||
"\\startTABLEfoot" $$ last rows $$ "\\stopTABLEfoot") $$
|
"\\startTABLEfoot" $$ last rows $$ "\\stopTABLEfoot") $$
|
||||||
"\\stopTABLE"
|
"\\stopTABLE"
|
||||||
|
|
||||||
tableRowToConTeXt :: PandocMonad m => Tabl -> [Alignment] -> [Double] -> [[Block]] -> WM m Doc
|
tableRowToConTeXt :: PandocMonad m => Tabl -> [Alignment] -> [Double] -> [[Block]] -> WM m (Doc Text)
|
||||||
tableRowToConTeXt Xtb aligns widths cols = do
|
tableRowToConTeXt Xtb aligns widths cols = do
|
||||||
cells <- mapM (tableColToConTeXt Xtb) $ zip3 aligns widths cols
|
cells <- mapM (tableColToConTeXt Xtb) $ zip3 aligns widths cols
|
||||||
return $ "\\startxrow" $$ vcat cells $$ "\\stopxrow"
|
return $ "\\startxrow" $$ vcat cells $$ "\\stopxrow"
|
||||||
|
@ -288,7 +294,7 @@ tableRowToConTeXt Ntb aligns widths cols = do
|
||||||
cells <- mapM (tableColToConTeXt Ntb) $ zip3 aligns widths cols
|
cells <- mapM (tableColToConTeXt Ntb) $ zip3 aligns widths cols
|
||||||
return $ vcat cells $$ "\\NC\\NR"
|
return $ vcat cells $$ "\\NC\\NR"
|
||||||
|
|
||||||
tableColToConTeXt :: PandocMonad m => Tabl -> (Alignment, Double, [Block]) -> WM m Doc
|
tableColToConTeXt :: PandocMonad m => Tabl -> (Alignment, Double, [Block]) -> WM m (Doc Text)
|
||||||
tableColToConTeXt tabl (align, width, blocks) = do
|
tableColToConTeXt tabl (align, width, blocks) = do
|
||||||
cellContents <- blockListToConTeXt blocks
|
cellContents <- blockListToConTeXt blocks
|
||||||
let colwidth = if width == 0
|
let colwidth = if width == 0
|
||||||
|
@ -301,23 +307,24 @@ tableColToConTeXt tabl (align, width, blocks) = do
|
||||||
where keys = hcat $ intersperse "," $ filter (not . isEmpty) [halign, colwidth]
|
where keys = hcat $ intersperse "," $ filter (not . isEmpty) [halign, colwidth]
|
||||||
tableCellToConTeXt tabl options cellContents
|
tableCellToConTeXt tabl options cellContents
|
||||||
|
|
||||||
tableCellToConTeXt :: PandocMonad m => Tabl -> Doc -> Doc -> WM m Doc
|
tableCellToConTeXt :: PandocMonad m
|
||||||
|
=> Tabl -> Doc Text -> Doc Text -> WM m (Doc Text)
|
||||||
tableCellToConTeXt Xtb options cellContents =
|
tableCellToConTeXt Xtb options cellContents =
|
||||||
return $ "\\startxcell" <> options <> cellContents <> " \\stopxcell"
|
return $ "\\startxcell" <> options <> cellContents <> " \\stopxcell"
|
||||||
tableCellToConTeXt Ntb options cellContents =
|
tableCellToConTeXt Ntb options cellContents =
|
||||||
return $ "\\NC" <> options <> cellContents
|
return $ "\\NC" <> options <> cellContents
|
||||||
|
|
||||||
alignToConTeXt :: Alignment -> Doc
|
alignToConTeXt :: Alignment -> Doc Text
|
||||||
alignToConTeXt align = case align of
|
alignToConTeXt align = case align of
|
||||||
AlignLeft -> "align=right"
|
AlignLeft -> "align=right"
|
||||||
AlignRight -> "align=left"
|
AlignRight -> "align=left"
|
||||||
AlignCenter -> "align=middle"
|
AlignCenter -> "align=middle"
|
||||||
AlignDefault -> empty
|
AlignDefault -> empty
|
||||||
|
|
||||||
listItemToConTeXt :: PandocMonad m => [Block] -> WM m Doc
|
listItemToConTeXt :: PandocMonad m => [Block] -> WM m (Doc Text)
|
||||||
listItemToConTeXt list = (("\\item" $$) . nest 2) <$> blockListToConTeXt list
|
listItemToConTeXt list = (("\\item" $$) . nest 2) <$> blockListToConTeXt list
|
||||||
|
|
||||||
defListItemToConTeXt :: PandocMonad m => ([Inline], [[Block]]) -> WM m Doc
|
defListItemToConTeXt :: PandocMonad m => ([Inline], [[Block]]) -> WM m (Doc Text)
|
||||||
defListItemToConTeXt (term, defs) = do
|
defListItemToConTeXt (term, defs) = do
|
||||||
term' <- inlineListToConTeXt term
|
term' <- inlineListToConTeXt term
|
||||||
def' <- liftM vsep $ mapM blockListToConTeXt defs
|
def' <- liftM vsep $ mapM blockListToConTeXt defs
|
||||||
|
@ -325,13 +332,13 @@ defListItemToConTeXt (term, defs) = do
|
||||||
"\\stopdescription" <> blankline
|
"\\stopdescription" <> blankline
|
||||||
|
|
||||||
-- | Convert list of block elements to ConTeXt.
|
-- | Convert list of block elements to ConTeXt.
|
||||||
blockListToConTeXt :: PandocMonad m => [Block] -> WM m Doc
|
blockListToConTeXt :: PandocMonad m => [Block] -> WM m (Doc Text)
|
||||||
blockListToConTeXt lst = liftM vcat $ mapM blockToConTeXt lst
|
blockListToConTeXt lst = liftM vcat $ mapM blockToConTeXt lst
|
||||||
|
|
||||||
-- | Convert list of inline elements to ConTeXt.
|
-- | Convert list of inline elements to ConTeXt.
|
||||||
inlineListToConTeXt :: PandocMonad m
|
inlineListToConTeXt :: PandocMonad m
|
||||||
=> [Inline] -- ^ Inlines to convert
|
=> [Inline] -- ^ Inlines to convert
|
||||||
-> WM m Doc
|
-> WM m (Doc Text)
|
||||||
inlineListToConTeXt lst = liftM hcat $ mapM inlineToConTeXt $ addStruts lst
|
inlineListToConTeXt lst = liftM hcat $ mapM inlineToConTeXt $ addStruts lst
|
||||||
-- We add a \strut after a line break that precedes a space,
|
-- We add a \strut after a line break that precedes a space,
|
||||||
-- or the space gets swallowed
|
-- or the space gets swallowed
|
||||||
|
@ -347,7 +354,7 @@ inlineListToConTeXt lst = liftM hcat $ mapM inlineToConTeXt $ addStruts lst
|
||||||
-- | Convert inline element to ConTeXt
|
-- | Convert inline element to ConTeXt
|
||||||
inlineToConTeXt :: PandocMonad m
|
inlineToConTeXt :: PandocMonad m
|
||||||
=> Inline -- ^ Inline to convert
|
=> Inline -- ^ Inline to convert
|
||||||
-> WM m Doc
|
-> WM m (Doc Text)
|
||||||
inlineToConTeXt (Emph lst) = do
|
inlineToConTeXt (Emph lst) = do
|
||||||
contents <- inlineListToConTeXt lst
|
contents <- inlineListToConTeXt lst
|
||||||
return $ braces $ "\\em " <> contents
|
return $ braces $ "\\em " <> contents
|
||||||
|
@ -435,7 +442,7 @@ inlineToConTeXt (Image attr@(_,cls,_) _ (src, _)) = do
|
||||||
dimList = showDim Width ++ showDim Height
|
dimList = showDim Width ++ showDim Height
|
||||||
dims = if null dimList
|
dims = if null dimList
|
||||||
then empty
|
then empty
|
||||||
else brackets $ cat (intersperse "," dimList)
|
else brackets $ mconcat (intersperse "," dimList)
|
||||||
clas = if null cls
|
clas = if null cls
|
||||||
then empty
|
then empty
|
||||||
else brackets $ text $ toLabel $ head cls
|
else brackets $ text $ toLabel $ head cls
|
||||||
|
@ -454,8 +461,8 @@ inlineToConTeXt (Note contents) = do
|
||||||
codeBlock _ = []
|
codeBlock _ = []
|
||||||
let codeBlocks = query codeBlock contents
|
let codeBlocks = query codeBlock contents
|
||||||
return $ if null codeBlocks
|
return $ if null codeBlocks
|
||||||
then text "\\footnote{" <> nest 2 contents' <> char '}'
|
then text "\\footnote{" <> nest 2 (chomp contents') <> char '}'
|
||||||
else text "\\startbuffer " <> nest 2 contents' <>
|
else text "\\startbuffer " <> nest 2 (chomp contents') <>
|
||||||
text "\\stopbuffer\\footnote{\\getbuffer}"
|
text "\\stopbuffer\\footnote{\\getbuffer}"
|
||||||
inlineToConTeXt (Span (_,_,kvs) ils) = do
|
inlineToConTeXt (Span (_,_,kvs) ils) = do
|
||||||
mblang <- fromBCP47 (lookup "lang" kvs)
|
mblang <- fromBCP47 (lookup "lang" kvs)
|
||||||
|
@ -474,7 +481,7 @@ sectionHeader :: PandocMonad m
|
||||||
=> Attr
|
=> Attr
|
||||||
-> Int
|
-> Int
|
||||||
-> [Inline]
|
-> [Inline]
|
||||||
-> WM m Doc
|
-> WM m (Doc Text)
|
||||||
sectionHeader (ident,classes,kvs) hdrLevel lst = do
|
sectionHeader (ident,classes,kvs) hdrLevel lst = do
|
||||||
opts <- gets stOptions
|
opts <- gets stOptions
|
||||||
contents <- inlineListToConTeXt lst
|
contents <- inlineListToConTeXt lst
|
||||||
|
@ -495,7 +502,7 @@ sectionHeader (ident,classes,kvs) hdrLevel lst = do
|
||||||
return $ starter <> levelText <> options <> blankline
|
return $ starter <> levelText <> options <> blankline
|
||||||
|
|
||||||
-- | Craft the section footer
|
-- | Craft the section footer
|
||||||
sectionFooter :: PandocMonad m => Attr -> Int -> WM m Doc
|
sectionFooter :: PandocMonad m => Attr -> Int -> WM m (Doc Text)
|
||||||
sectionFooter attr hdrLevel = do
|
sectionFooter attr hdrLevel = do
|
||||||
opts <- gets stOptions
|
opts <- gets stOptions
|
||||||
levelText <- sectionLevelToText opts attr hdrLevel
|
levelText <- sectionLevelToText opts attr hdrLevel
|
||||||
|
@ -504,7 +511,7 @@ sectionFooter attr hdrLevel = do
|
||||||
else empty
|
else empty
|
||||||
|
|
||||||
-- | Generate a textual representation of the section level
|
-- | Generate a textual representation of the section level
|
||||||
sectionLevelToText :: PandocMonad m => WriterOptions -> Attr -> Int -> WM m Doc
|
sectionLevelToText :: PandocMonad m => WriterOptions -> Attr -> Int -> WM m (Doc Text)
|
||||||
sectionLevelToText opts (_,classes,_) hdrLevel = do
|
sectionLevelToText opts (_,classes,_) hdrLevel = do
|
||||||
let level' = case writerTopLevelDivision opts of
|
let level' = case writerTopLevelDivision opts of
|
||||||
TopLevelPart -> hdrLevel - 2
|
TopLevelPart -> hdrLevel - 2
|
||||||
|
|
|
@ -29,7 +29,7 @@ import Text.Pandoc.Lua (Global (..), LuaException (LuaException),
|
||||||
runLua, setGlobals)
|
runLua, setGlobals)
|
||||||
import Text.Pandoc.Lua.Util (addField, dofileWithTraceback)
|
import Text.Pandoc.Lua.Util (addField, dofileWithTraceback)
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Templates
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import qualified Text.Pandoc.UTF8 as UTF8
|
import qualified Text.Pandoc.UTF8 as UTF8
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
|
||||||
when (stat /= Lua.OK) $
|
when (stat /= Lua.OK) $
|
||||||
Lua.tostring' (-1) >>= throw . PandocLuaException . UTF8.toString
|
Lua.tostring' (-1) >>= throw . PandocLuaException . UTF8.toString
|
||||||
rendered <- docToCustom opts doc
|
rendered <- docToCustom opts doc
|
||||||
context <- metaToJSON opts
|
context <- metaToContext opts
|
||||||
blockListToCustom
|
blockListToCustom
|
||||||
inlineListToCustom
|
inlineListToCustom
|
||||||
meta
|
meta
|
||||||
|
@ -108,9 +108,9 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
|
||||||
let (body, context) = case res of
|
let (body, context) = case res of
|
||||||
Left (LuaException msg) -> throw (PandocLuaException msg)
|
Left (LuaException msg) -> throw (PandocLuaException msg)
|
||||||
Right x -> x
|
Right x -> x
|
||||||
return $
|
return $ pack $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> pack body
|
Nothing -> body
|
||||||
Just tpl -> renderTemplate tpl $ setField "body" body context
|
Just tpl -> renderTemplate tpl $ setField "body" body context
|
||||||
|
|
||||||
docToCustom :: WriterOptions -> Pandoc -> Lua String
|
docToCustom :: WriterOptions -> Pandoc -> Lua String
|
||||||
|
|
|
@ -20,6 +20,7 @@ import Data.Generics (everywhere, mkT)
|
||||||
import Data.List (isPrefixOf, stripPrefix)
|
import Data.List (isPrefixOf, stripPrefix)
|
||||||
import Data.Monoid (Any (..))
|
import Data.Monoid (Any (..))
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
import qualified Text.Pandoc.Builder as B
|
import qualified Text.Pandoc.Builder as B
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
|
@ -27,12 +28,12 @@ import Text.Pandoc.Highlighting (languages, languagesByExtension)
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Pandoc.Walk
|
import Text.Pandoc.Walk
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
import Text.Pandoc.Writers.Shared
|
|
||||||
import Text.Pandoc.XML
|
import Text.Pandoc.XML
|
||||||
import Text.TeXMath
|
import Text.TeXMath
|
||||||
import qualified Text.XML.Light as Xml
|
import qualified Text.XML.Light as Xml
|
||||||
|
@ -45,7 +46,7 @@ type DB = ReaderT DocBookVersion
|
||||||
-- | Convert list of authors to a docbook <author> section
|
-- | Convert list of authors to a docbook <author> section
|
||||||
authorToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m B.Inlines
|
authorToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m B.Inlines
|
||||||
authorToDocbook opts name' = do
|
authorToDocbook opts name' = do
|
||||||
name <- render Nothing <$> inlinesToDocbook opts name'
|
name <- T.unpack . render Nothing <$> inlinesToDocbook opts name'
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
|
@ -81,8 +82,6 @@ writeDocbook opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
-- The numbering here follows LaTeX's internal numbering
|
-- The numbering here follows LaTeX's internal numbering
|
||||||
let startLvl = case writerTopLevelDivision opts of
|
let startLvl = case writerTopLevelDivision opts of
|
||||||
TopLevelPart -> -1
|
TopLevelPart -> -1
|
||||||
|
@ -91,26 +90,25 @@ writeDocbook opts (Pandoc meta blocks) = do
|
||||||
TopLevelDefault -> 1
|
TopLevelDefault -> 1
|
||||||
auths' <- mapM (authorToDocbook opts) $ docAuthors meta
|
auths' <- mapM (authorToDocbook opts) $ docAuthors meta
|
||||||
let meta' = B.setMeta "author" auths' meta
|
let meta' = B.setMeta "author" auths' meta
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap (render' . vcat) .
|
(fmap vcat .
|
||||||
mapM (elementToDocbook opts startLvl) .
|
mapM (elementToDocbook opts startLvl) .
|
||||||
hierarchicalize)
|
hierarchicalize)
|
||||||
(fmap render' . inlinesToDocbook opts)
|
(inlinesToDocbook opts)
|
||||||
meta'
|
meta'
|
||||||
main <- (render' . vcat) <$> mapM (elementToDocbook opts startLvl) elements
|
main <- vcat <$> mapM (elementToDocbook opts startLvl) elements
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$
|
$ defField "mathml" (case writerHTMLMathMethod opts of
|
||||||
defField "mathml" (case writerHTMLMathMethod opts of
|
|
||||||
MathML -> True
|
MathML -> True
|
||||||
_ -> False) metadata
|
_ -> False) metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
(if writerPreferAscii opts then toEntities else id) $
|
(if writerPreferAscii opts then fmap toEntities else id) $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Convert an Element to Docbook.
|
-- | Convert an Element to Docbook.
|
||||||
elementToDocbook :: PandocMonad m => WriterOptions -> Int -> Element -> DB m Doc
|
elementToDocbook :: PandocMonad m => WriterOptions -> Int -> Element -> DB m (Doc Text)
|
||||||
elementToDocbook opts _ (Blk block) = blockToDocbook opts block
|
elementToDocbook opts _ (Blk block) = blockToDocbook opts block
|
||||||
elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) = do
|
elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) = do
|
||||||
version <- ask
|
version <- ask
|
||||||
|
@ -138,7 +136,7 @@ elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) = do
|
||||||
inTagsSimple "title" title' $$ vcat contents
|
inTagsSimple "title" title' $$ vcat contents
|
||||||
|
|
||||||
-- | Convert a list of Pandoc blocks to Docbook.
|
-- | Convert a list of Pandoc blocks to Docbook.
|
||||||
blocksToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m Doc
|
blocksToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m (Doc Text)
|
||||||
blocksToDocbook opts = fmap vcat . mapM (blockToDocbook opts)
|
blocksToDocbook opts = fmap vcat . mapM (blockToDocbook opts)
|
||||||
|
|
||||||
-- | Auxiliary function to convert Plain block to Para.
|
-- | Auxiliary function to convert Plain block to Para.
|
||||||
|
@ -149,13 +147,13 @@ plainToPara x = x
|
||||||
-- | Convert a list of pairs of terms and definitions into a list of
|
-- | Convert a list of pairs of terms and definitions into a list of
|
||||||
-- Docbook varlistentrys.
|
-- Docbook varlistentrys.
|
||||||
deflistItemsToDocbook :: PandocMonad m
|
deflistItemsToDocbook :: PandocMonad m
|
||||||
=> WriterOptions -> [([Inline],[[Block]])] -> DB m Doc
|
=> WriterOptions -> [([Inline],[[Block]])] -> DB m (Doc Text)
|
||||||
deflistItemsToDocbook opts items =
|
deflistItemsToDocbook opts items =
|
||||||
vcat <$> mapM (uncurry (deflistItemToDocbook opts)) items
|
vcat <$> mapM (uncurry (deflistItemToDocbook opts)) items
|
||||||
|
|
||||||
-- | Convert a term and a list of blocks into a Docbook varlistentry.
|
-- | Convert a term and a list of blocks into a Docbook varlistentry.
|
||||||
deflistItemToDocbook :: PandocMonad m
|
deflistItemToDocbook :: PandocMonad m
|
||||||
=> WriterOptions -> [Inline] -> [[Block]] -> DB m Doc
|
=> WriterOptions -> [Inline] -> [[Block]] -> DB m (Doc Text)
|
||||||
deflistItemToDocbook opts term defs = do
|
deflistItemToDocbook opts term defs = do
|
||||||
term' <- inlinesToDocbook opts term
|
term' <- inlinesToDocbook opts term
|
||||||
def' <- blocksToDocbook opts $ concatMap (map plainToPara) defs
|
def' <- blocksToDocbook opts $ concatMap (map plainToPara) defs
|
||||||
|
@ -164,15 +162,15 @@ deflistItemToDocbook opts term defs = do
|
||||||
inTagsIndented "listitem" def'
|
inTagsIndented "listitem" def'
|
||||||
|
|
||||||
-- | Convert a list of lists of blocks to a list of Docbook list items.
|
-- | Convert a list of lists of blocks to a list of Docbook list items.
|
||||||
listItemsToDocbook :: PandocMonad m => WriterOptions -> [[Block]] -> DB m Doc
|
listItemsToDocbook :: PandocMonad m => WriterOptions -> [[Block]] -> DB m (Doc Text)
|
||||||
listItemsToDocbook opts items = vcat <$> mapM (listItemToDocbook opts) items
|
listItemsToDocbook opts items = vcat <$> mapM (listItemToDocbook opts) items
|
||||||
|
|
||||||
-- | Convert a list of blocks into a Docbook list item.
|
-- | Convert a list of blocks into a Docbook list item.
|
||||||
listItemToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m Doc
|
listItemToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m (Doc Text)
|
||||||
listItemToDocbook opts item =
|
listItemToDocbook opts item =
|
||||||
inTagsIndented "listitem" <$> blocksToDocbook opts (map plainToPara item)
|
inTagsIndented "listitem" <$> blocksToDocbook opts (map plainToPara item)
|
||||||
|
|
||||||
imageToDocbook :: WriterOptions -> Attr -> String -> Doc
|
imageToDocbook :: WriterOptions -> Attr -> String -> Doc Text
|
||||||
imageToDocbook _ attr src = selfClosingTag "imagedata" $
|
imageToDocbook _ attr src = selfClosingTag "imagedata" $
|
||||||
("fileref", src) : idAndRole attr ++ dims
|
("fileref", src) : idAndRole attr ++ dims
|
||||||
where
|
where
|
||||||
|
@ -182,7 +180,7 @@ imageToDocbook _ attr src = selfClosingTag "imagedata" $
|
||||||
Nothing -> []
|
Nothing -> []
|
||||||
|
|
||||||
-- | Convert a Pandoc block element to Docbook.
|
-- | Convert a Pandoc block element to Docbook.
|
||||||
blockToDocbook :: PandocMonad m => WriterOptions -> Block -> DB m Doc
|
blockToDocbook :: PandocMonad m => WriterOptions -> Block -> DB m (Doc Text)
|
||||||
blockToDocbook _ Null = return empty
|
blockToDocbook _ Null = return empty
|
||||||
-- Add ids to paragraphs in divs with ids - this is needed for
|
-- Add ids to paragraphs in divs with ids - this is needed for
|
||||||
-- pandoc-citeproc to get link anchors in bibliographies:
|
-- pandoc-citeproc to get link anchors in bibliographies:
|
||||||
|
@ -312,23 +310,23 @@ alignmentToString alignment = case alignment of
|
||||||
tableRowToDocbook :: PandocMonad m
|
tableRowToDocbook :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> DB m Doc
|
-> DB m (Doc Text)
|
||||||
tableRowToDocbook opts cols =
|
tableRowToDocbook opts cols =
|
||||||
(inTagsIndented "row" . vcat) <$> mapM (tableItemToDocbook opts) cols
|
(inTagsIndented "row" . vcat) <$> mapM (tableItemToDocbook opts) cols
|
||||||
|
|
||||||
tableItemToDocbook :: PandocMonad m
|
tableItemToDocbook :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> DB m Doc
|
-> DB m (Doc Text)
|
||||||
tableItemToDocbook opts item =
|
tableItemToDocbook opts item =
|
||||||
(inTags True "entry" [] . vcat) <$> mapM (blockToDocbook opts) item
|
(inTags True "entry" [] . vcat) <$> mapM (blockToDocbook opts) item
|
||||||
|
|
||||||
-- | Convert a list of inline elements to Docbook.
|
-- | Convert a list of inline elements to Docbook.
|
||||||
inlinesToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m Doc
|
inlinesToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m (Doc Text)
|
||||||
inlinesToDocbook opts lst = hcat <$> mapM (inlineToDocbook opts) lst
|
inlinesToDocbook opts lst = hcat <$> mapM (inlineToDocbook opts) lst
|
||||||
|
|
||||||
-- | Convert an inline element to Docbook.
|
-- | Convert an inline element to Docbook.
|
||||||
inlineToDocbook :: PandocMonad m => WriterOptions -> Inline -> DB m Doc
|
inlineToDocbook :: PandocMonad m => WriterOptions -> Inline -> DB m (Doc Text)
|
||||||
inlineToDocbook _ (Str str) = return $ text $ escapeStringForXML str
|
inlineToDocbook _ (Str str) = return $ text $ escapeStringForXML str
|
||||||
inlineToDocbook opts (Emph lst) =
|
inlineToDocbook opts (Emph lst) =
|
||||||
inTagsSimple "emphasis" <$> inlinesToDocbook opts lst
|
inTagsSimple "emphasis" <$> inlinesToDocbook opts lst
|
||||||
|
|
|
@ -37,7 +37,7 @@ import Text.Pandoc.Options (WrapOption (..), WriterOptions (writerTableOfContent
|
||||||
import Text.Pandoc.Shared (camelCaseToHyphenated, escapeURI, isURI, linesToPara,
|
import Text.Pandoc.Shared (camelCaseToHyphenated, escapeURI, isURI, linesToPara,
|
||||||
removeFormatting, substitute, trimr)
|
removeFormatting, substitute, trimr)
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared (defField, metaToJSON)
|
import Text.Pandoc.Writers.Shared (defField, metaToContext)
|
||||||
|
|
||||||
data WriterState = WriterState {
|
data WriterState = WriterState {
|
||||||
}
|
}
|
||||||
|
@ -70,15 +70,15 @@ runDokuWiki = flip evalStateT def . flip runReaderT def
|
||||||
pandocToDokuWiki :: PandocMonad m
|
pandocToDokuWiki :: PandocMonad m
|
||||||
=> WriterOptions -> Pandoc -> DokuWiki m Text
|
=> WriterOptions -> Pandoc -> DokuWiki m Text
|
||||||
pandocToDokuWiki opts (Pandoc meta blocks) = do
|
pandocToDokuWiki opts (Pandoc meta blocks) = do
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap trimr . blockListToDokuWiki opts)
|
(fmap trimr . blockListToDokuWiki opts)
|
||||||
(inlineListToDokuWiki opts)
|
(fmap trimr . inlineListToDokuWiki opts)
|
||||||
meta
|
meta
|
||||||
body <- blockListToDokuWiki opts blocks
|
body <- blockListToDokuWiki opts blocks
|
||||||
let main = pack body
|
let main = body
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "toc" (writerTableOfContents opts) metadata
|
$ defField "toc" (writerTableOfContents opts) metadata
|
||||||
return $
|
return $ pack $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
|
@ -36,6 +36,7 @@ import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, mapMaybe)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import Data.String (fromString)
|
import Data.String (fromString)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import Network.HTTP (urlEncode)
|
import Network.HTTP (urlEncode)
|
||||||
import Network.URI (URI (..), parseURIReference)
|
import Network.URI (URI (..), parseURIReference)
|
||||||
|
@ -53,7 +54,8 @@ import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Slides
|
import Text.Pandoc.Slides
|
||||||
import Text.Pandoc.Templates
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
|
import Text.DocTemplates (Context(..))
|
||||||
import Text.Pandoc.Walk
|
import Text.Pandoc.Walk
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -71,7 +73,6 @@ import qualified Text.Blaze.Html5 as H5
|
||||||
import qualified Text.Blaze.Html5.Attributes as A5
|
import qualified Text.Blaze.Html5.Attributes as A5
|
||||||
#endif
|
#endif
|
||||||
import Control.Monad.Except (throwError)
|
import Control.Monad.Except (throwError)
|
||||||
import Data.Aeson (Value)
|
|
||||||
import System.FilePath (takeBaseName)
|
import System.FilePath (takeBaseName)
|
||||||
import Text.Blaze.Html.Renderer.Text (renderHtml)
|
import Text.Blaze.Html.Renderer.Text (renderHtml)
|
||||||
import qualified Text.Blaze.XHtml1.Transitional as H
|
import qualified Text.Blaze.XHtml1.Transitional as H
|
||||||
|
@ -215,17 +216,17 @@ writeHtmlString' st opts d = do
|
||||||
Nothing -> return $ renderHtml' body
|
Nothing -> return $ renderHtml' body
|
||||||
Just tpl -> do
|
Just tpl -> do
|
||||||
-- warn if empty lang
|
-- warn if empty lang
|
||||||
when (isNothing (getField "lang" context :: Maybe String)) $
|
when (isNothing (getField "lang" context :: Maybe Text)) $
|
||||||
report NoLangSpecified
|
report NoLangSpecified
|
||||||
-- check for empty pagetitle
|
-- check for empty pagetitle
|
||||||
context' <-
|
context' <-
|
||||||
case getField "pagetitle" context of
|
case getField "pagetitle" context of
|
||||||
Just (s :: String) | not (null s) -> return context
|
Just (s :: Text) | not (T.null s) -> return context
|
||||||
_ -> do
|
_ -> do
|
||||||
let fallback = fromMaybe "Untitled" $ takeBaseName <$>
|
let fallback = maybe "Untitled" takeBaseName $
|
||||||
lookup "sourcefile" (writerVariables opts)
|
lookup "sourcefile" (writerVariables opts)
|
||||||
report $ NoTitleElement fallback
|
report $ NoTitleElement fallback
|
||||||
return $ resetField "pagetitle" fallback context
|
return $ resetField "pagetitle" (T.pack fallback) context
|
||||||
return $ renderTemplate tpl
|
return $ renderTemplate tpl
|
||||||
(defField "body" (renderHtml' body) context')
|
(defField "body" (renderHtml' body) context')
|
||||||
|
|
||||||
|
@ -244,9 +245,9 @@ writeHtml' st opts d =
|
||||||
pandocToHtml :: PandocMonad m
|
pandocToHtml :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> Pandoc
|
-> Pandoc
|
||||||
-> StateT WriterState m (Html, Value)
|
-> StateT WriterState m (Html, Context Text)
|
||||||
pandocToHtml opts (Pandoc meta blocks) = do
|
pandocToHtml opts (Pandoc meta blocks) = do
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap renderHtml' . blockListToHtml opts)
|
(fmap renderHtml' . blockListToHtml opts)
|
||||||
(fmap renderHtml' . inlineListToHtml opts)
|
(fmap renderHtml' . inlineListToHtml opts)
|
||||||
meta
|
meta
|
||||||
|
@ -298,7 +299,7 @@ pandocToHtml opts (Pandoc meta blocks) = do
|
||||||
let context = (if stHighlighting st
|
let context = (if stHighlighting st
|
||||||
then case writerHighlightStyle opts of
|
then case writerHighlightStyle opts of
|
||||||
Just sty -> defField "highlighting-css"
|
Just sty -> defField "highlighting-css"
|
||||||
(styleToCss sty)
|
(T.pack $ styleToCss sty)
|
||||||
Nothing -> id
|
Nothing -> id
|
||||||
else id) $
|
else id) $
|
||||||
(if stMath st
|
(if stMath st
|
||||||
|
@ -307,7 +308,7 @@ pandocToHtml opts (Pandoc meta blocks) = do
|
||||||
(case writerHTMLMathMethod opts of
|
(case writerHTMLMathMethod opts of
|
||||||
MathJax u -> defField "mathjax" True .
|
MathJax u -> defField "mathjax" True .
|
||||||
defField "mathjaxurl"
|
defField "mathjaxurl"
|
||||||
(takeWhile (/='?') u)
|
(T.pack $ takeWhile (/='?') u)
|
||||||
_ -> defField "mathjax" False) $
|
_ -> defField "mathjax" False) $
|
||||||
defField "quotes" (stQuotes st) $
|
defField "quotes" (stQuotes st) $
|
||||||
-- for backwards compatibility we populate toc
|
-- for backwards compatibility we populate toc
|
||||||
|
@ -315,16 +316,18 @@ pandocToHtml opts (Pandoc meta blocks) = do
|
||||||
-- boolean:
|
-- boolean:
|
||||||
maybe id (defField "toc") toc $
|
maybe id (defField "toc") toc $
|
||||||
maybe id (defField "table-of-contents") toc $
|
maybe id (defField "table-of-contents") toc $
|
||||||
defField "author-meta" authsMeta $
|
defField "author-meta" (map T.pack authsMeta) $
|
||||||
maybe id (defField "date-meta") (normalizeDate dateMeta) $
|
maybe id (defField "date-meta" . T.pack)
|
||||||
defField "pagetitle" (stringifyHTML (docTitle meta)) $
|
(normalizeDate dateMeta) $
|
||||||
defField "idprefix" (writerIdentifierPrefix opts) $
|
defField "pagetitle"
|
||||||
|
(T.pack . stringifyHTML . docTitle $ meta) $
|
||||||
|
defField "idprefix" (T.pack $ writerIdentifierPrefix opts) $
|
||||||
-- these should maybe be set in pandoc.hs
|
-- these should maybe be set in pandoc.hs
|
||||||
defField "slidy-url"
|
defField "slidy-url"
|
||||||
("https://www.w3.org/Talks/Tools/Slidy2" :: String) $
|
("https://www.w3.org/Talks/Tools/Slidy2" :: Text) $
|
||||||
defField "slideous-url" ("slideous" :: String) $
|
defField "slideous-url" ("slideous" :: Text) $
|
||||||
defField "revealjs-url" ("reveal.js" :: String) $
|
defField "revealjs-url" ("reveal.js" :: Text) $
|
||||||
defField "s5-url" ("s5/default" :: String) $
|
defField "s5-url" ("s5/default" :: Text) $
|
||||||
defField "html5" (stHtml5 st)
|
defField "html5" (stHtml5 st)
|
||||||
metadata
|
metadata
|
||||||
return (thebody, context)
|
return (thebody, context)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -49,23 +49,20 @@ pandocToHaddock opts (Pandoc meta blocks) = do
|
||||||
body <- blockListToHaddock opts blocks
|
body <- blockListToHaddock opts blocks
|
||||||
st <- get
|
st <- get
|
||||||
notes' <- notesToHaddock opts (reverse $ stNotes st)
|
notes' <- notesToHaddock opts (reverse $ stNotes st)
|
||||||
let render' :: Doc -> Text
|
let main = body <> (if isEmpty notes' then empty else blankline <> notes')
|
||||||
render' = render colwidth
|
metadata <- metaToContext opts
|
||||||
let main = render' $ body <>
|
(blockListToHaddock opts)
|
||||||
(if isEmpty notes' then empty else blankline <> notes')
|
(fmap chomp . inlineListToHaddock opts)
|
||||||
metadata <- metaToJSON opts
|
|
||||||
(fmap render' . blockListToHaddock opts)
|
|
||||||
(fmap render' . inlineListToHaddock opts)
|
|
||||||
meta
|
meta
|
||||||
let context = defField "body" main metadata
|
let context = defField "body" main metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Return haddock representation of notes.
|
-- | Return haddock representation of notes.
|
||||||
notesToHaddock :: PandocMonad m
|
notesToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -> [[Block]] -> StateT WriterState m Doc
|
=> WriterOptions -> [[Block]] -> StateT WriterState m (Doc Text)
|
||||||
notesToHaddock opts notes =
|
notesToHaddock opts notes =
|
||||||
if null notes
|
if null notes
|
||||||
then return empty
|
then return empty
|
||||||
|
@ -82,7 +79,7 @@ escapeString = escapeStringUsing haddockEscapes
|
||||||
blockToHaddock :: PandocMonad m
|
blockToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
blockToHaddock _ Null = return empty
|
blockToHaddock _ Null = return empty
|
||||||
blockToHaddock opts (Div _ ils) = do
|
blockToHaddock opts (Div _ ils) = do
|
||||||
contents <- blockListToHaddock opts ils
|
contents <- blockListToHaddock opts ils
|
||||||
|
@ -129,7 +126,7 @@ blockToHaddock opts (Table caption aligns widths headers rows) = do
|
||||||
return $ prefixed "> " (tbl $$ blankline $$ caption'') $$ blankline
|
return $ prefixed "> " (tbl $$ blankline $$ caption'') $$ blankline
|
||||||
blockToHaddock opts (BulletList items) = do
|
blockToHaddock opts (BulletList items) = do
|
||||||
contents <- mapM (bulletListItemToHaddock opts) items
|
contents <- mapM (bulletListItemToHaddock opts) items
|
||||||
return $ cat contents <> blankline
|
return $ (if isTightList items then vcat else vsep) contents <> blankline
|
||||||
blockToHaddock opts (OrderedList (start,_,delim) items) = do
|
blockToHaddock opts (OrderedList (start,_,delim) items) = do
|
||||||
let attribs = (start, Decimal, delim)
|
let attribs = (start, Decimal, delim)
|
||||||
let markers = orderedListMarkers attribs
|
let markers = orderedListMarkers attribs
|
||||||
|
@ -137,69 +134,72 @@ blockToHaddock opts (OrderedList (start,_,delim) items) = do
|
||||||
then m ++ replicate (3 - length m) ' '
|
then m ++ replicate (3 - length m) ' '
|
||||||
else m) markers
|
else m) markers
|
||||||
contents <- zipWithM (orderedListItemToHaddock opts) markers' items
|
contents <- zipWithM (orderedListItemToHaddock opts) markers' items
|
||||||
return $ cat contents <> blankline
|
return $ (if isTightList items then vcat else vsep) contents <> blankline
|
||||||
blockToHaddock opts (DefinitionList items) = do
|
blockToHaddock opts (DefinitionList items) = do
|
||||||
contents <- mapM (definitionListItemToHaddock opts) items
|
contents <- mapM (definitionListItemToHaddock opts) items
|
||||||
return $ cat contents <> blankline
|
return $ vcat contents <> blankline
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to haddock
|
-- | Convert bullet list item (list of blocks) to haddock
|
||||||
bulletListItemToHaddock :: PandocMonad m
|
bulletListItemToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -> [Block] -> StateT WriterState m Doc
|
=> WriterOptions -> [Block] -> StateT WriterState m (Doc Text)
|
||||||
bulletListItemToHaddock opts items = do
|
bulletListItemToHaddock opts items = do
|
||||||
contents <- blockListToHaddock opts items
|
contents <- blockListToHaddock opts items
|
||||||
let sps = replicate (writerTabStop opts - 2) ' '
|
let sps = replicate (writerTabStop opts - 2) ' '
|
||||||
let start = text ('-' : ' ' : sps)
|
let start = text ('-' : ' ' : sps)
|
||||||
-- remove trailing blank line if it is a tight list
|
return $ hang (writerTabStop opts) start contents $$
|
||||||
let contents' = case reverse items of
|
if endsWithPlain items
|
||||||
(BulletList xs:_) | isTightList xs ->
|
then cr
|
||||||
chomp contents <> cr
|
else blankline
|
||||||
(OrderedList _ xs:_) | isTightList xs ->
|
|
||||||
chomp contents <> cr
|
|
||||||
_ -> contents
|
|
||||||
return $ hang (writerTabStop opts) start $ contents' <> cr
|
|
||||||
|
|
||||||
-- | Convert ordered list item (a list of blocks) to haddock
|
-- | Convert ordered list item (a list of blocks) to haddock
|
||||||
orderedListItemToHaddock :: PandocMonad m
|
orderedListItemToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -- ^ options
|
=> WriterOptions -- ^ options
|
||||||
-> String -- ^ list item marker
|
-> String -- ^ list item marker
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
orderedListItemToHaddock opts marker items = do
|
orderedListItemToHaddock opts marker items = do
|
||||||
contents <- blockListToHaddock opts items
|
contents <- blockListToHaddock opts items
|
||||||
let sps = case length marker - writerTabStop opts of
|
let sps = case length marker - writerTabStop opts of
|
||||||
n | n > 0 -> text $ replicate n ' '
|
n | n > 0 -> text $ replicate n ' '
|
||||||
_ -> text " "
|
_ -> text " "
|
||||||
let start = text marker <> sps
|
let start = text marker <> sps
|
||||||
return $ hang (writerTabStop opts) start $ contents <> cr
|
return $ hang (writerTabStop opts) start contents $$
|
||||||
|
if endsWithPlain items
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert definition list item (label, list of blocks) to haddock
|
-- | Convert definition list item (label, list of blocks) to haddock
|
||||||
definitionListItemToHaddock :: PandocMonad m
|
definitionListItemToHaddock :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Inline],[[Block]])
|
-> ([Inline],[[Block]])
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
definitionListItemToHaddock opts (label, defs) = do
|
definitionListItemToHaddock opts (label, defs) = do
|
||||||
labelText <- inlineListToHaddock opts label
|
labelText <- inlineListToHaddock opts label
|
||||||
defs' <- mapM (mapM (blockToHaddock opts)) defs
|
defs' <- mapM (mapM (blockToHaddock opts)) defs
|
||||||
let contents = vcat $ map (\d -> hang 4 empty $ vcat d <> cr) defs'
|
let contents = (if isTightList defs then vcat else vsep) $
|
||||||
return $ nowrap (brackets labelText) <> cr <> contents <> cr
|
map (\d -> hang 4 empty $ vcat d <> cr) defs'
|
||||||
|
return $ nowrap (brackets labelText) $$ contents $$
|
||||||
|
if isTightList defs
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert list of Pandoc block elements to haddock
|
-- | Convert list of Pandoc block elements to haddock
|
||||||
blockListToHaddock :: PandocMonad m
|
blockListToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
blockListToHaddock opts blocks =
|
blockListToHaddock opts blocks =
|
||||||
cat <$> mapM (blockToHaddock opts) blocks
|
mconcat <$> mapM (blockToHaddock opts) blocks
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to haddock.
|
-- | Convert list of Pandoc inline elements to haddock.
|
||||||
inlineListToHaddock :: PandocMonad m
|
inlineListToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -> [Inline] -> StateT WriterState m Doc
|
=> WriterOptions -> [Inline] -> StateT WriterState m (Doc Text)
|
||||||
inlineListToHaddock opts lst =
|
inlineListToHaddock opts lst =
|
||||||
cat <$> mapM (inlineToHaddock opts) lst
|
mconcat <$> mapM (inlineToHaddock opts) lst
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to haddock.
|
-- | Convert Pandoc inline element to haddock.
|
||||||
inlineToHaddock :: PandocMonad m
|
inlineToHaddock :: PandocMonad m
|
||||||
=> WriterOptions -> Inline -> StateT WriterState m Doc
|
=> WriterOptions -> Inline -> StateT WriterState m (Doc Text)
|
||||||
inlineToHaddock opts (Span (ident,_,_) ils) = do
|
inlineToHaddock opts (Span (ident,_,_) ils) = do
|
||||||
contents <- inlineListToHaddock opts ils
|
contents <- inlineListToHaddock opts ils
|
||||||
if not (null ident) && null ils
|
if not (null ident) && null ils
|
||||||
|
|
|
@ -31,7 +31,7 @@ import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared (isURI, linesToPara, splitBy)
|
import Text.Pandoc.Shared (isURI, linesToPara, splitBy)
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Math (texMathToInlines)
|
import Text.Pandoc.Writers.Math (texMathToInlines)
|
||||||
|
@ -136,21 +136,18 @@ writeICML opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
render' :: Doc -> Text
|
renderMeta f s = fst <$> runStateT (f opts [] s) defaultWriterState
|
||||||
render' = render colwidth
|
metadata <- metaToContext opts
|
||||||
renderMeta f s = liftM (render' . fst) $ runStateT (f opts [] s) defaultWriterState
|
|
||||||
metadata <- metaToJSON opts
|
|
||||||
(renderMeta blocksToICML)
|
(renderMeta blocksToICML)
|
||||||
(renderMeta inlinesToICML)
|
(renderMeta inlinesToICML)
|
||||||
meta
|
meta
|
||||||
(doc, st) <- runStateT (blocksToICML opts [] blocks) defaultWriterState
|
(main, st) <- runStateT (blocksToICML opts [] blocks) defaultWriterState
|
||||||
let main = render' doc
|
let context = defField "body" main
|
||||||
context = defField "body" main
|
$ defField "charStyles" (charStylesToDoc st)
|
||||||
$ defField "charStyles" (render' $ charStylesToDoc st)
|
$ defField "parStyles" (parStylesToDoc st)
|
||||||
$ defField "parStyles" (render' $ parStylesToDoc st)
|
$ defField "hyperlinks" (hyperlinksToDoc $ links st) metadata
|
||||||
$ defField "hyperlinks" (render' $ hyperlinksToDoc $ links st) metadata
|
return $ render colwidth $
|
||||||
return $
|
(if writerPreferAscii opts then fmap toEntities else id) $
|
||||||
(if writerPreferAscii opts then toEntities else id) $
|
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -161,7 +158,7 @@ contains s rule =
|
||||||
[snd rule | (fst rule) `isInfixOf` s]
|
[snd rule | (fst rule) `isInfixOf` s]
|
||||||
|
|
||||||
-- | The monospaced font to use as default.
|
-- | The monospaced font to use as default.
|
||||||
monospacedFont :: Doc
|
monospacedFont :: Doc Text
|
||||||
monospacedFont = inTags False "AppliedFont" [("type", "string")] $ text "Courier New"
|
monospacedFont = inTags False "AppliedFont" [("type", "string")] $ text "Courier New"
|
||||||
|
|
||||||
-- | How much to indent blockquotes etc.
|
-- | How much to indent blockquotes etc.
|
||||||
|
@ -177,7 +174,7 @@ lineSeparator :: String
|
||||||
lineSeparator = "
"
|
lineSeparator = "
"
|
||||||
|
|
||||||
-- | Convert a WriterState with its block styles to the ICML listing of Paragraph Styles.
|
-- | Convert a WriterState with its block styles to the ICML listing of Paragraph Styles.
|
||||||
parStylesToDoc :: WriterState -> Doc
|
parStylesToDoc :: WriterState -> Doc Text
|
||||||
parStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ blockStyles st
|
parStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ blockStyles st
|
||||||
where
|
where
|
||||||
makeStyle s =
|
makeStyle s =
|
||||||
|
@ -243,7 +240,7 @@ parStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ blockStyles st
|
||||||
in inTags True "ParagraphStyle" ([("Self", "ParagraphStyle/"++s), ("Name", s)] ++ attrs') props
|
in inTags True "ParagraphStyle" ([("Self", "ParagraphStyle/"++s), ("Name", s)] ++ attrs') props
|
||||||
|
|
||||||
-- | Convert a WriterState with its inline styles to the ICML listing of Character Styles.
|
-- | Convert a WriterState with its inline styles to the ICML listing of Character Styles.
|
||||||
charStylesToDoc :: WriterState -> Doc
|
charStylesToDoc :: WriterState -> Doc Text
|
||||||
charStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ inlineStyles st
|
charStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ inlineStyles st
|
||||||
where
|
where
|
||||||
makeStyle s =
|
makeStyle s =
|
||||||
|
@ -274,7 +271,7 @@ escapeColons (x:xs)
|
||||||
escapeColons [] = []
|
escapeColons [] = []
|
||||||
|
|
||||||
-- | Convert a list of (identifier, url) pairs to the ICML listing of hyperlinks.
|
-- | Convert a list of (identifier, url) pairs to the ICML listing of hyperlinks.
|
||||||
hyperlinksToDoc :: Hyperlink -> Doc
|
hyperlinksToDoc :: Hyperlink -> Doc Text
|
||||||
hyperlinksToDoc [] = empty
|
hyperlinksToDoc [] = empty
|
||||||
hyperlinksToDoc (x:xs) = hyp x $$ hyperlinksToDoc xs
|
hyperlinksToDoc (x:xs) = hyp x $$ hyperlinksToDoc xs
|
||||||
where
|
where
|
||||||
|
@ -293,13 +290,13 @@ dynamicStyleKey :: String
|
||||||
dynamicStyleKey = "custom-style"
|
dynamicStyleKey = "custom-style"
|
||||||
|
|
||||||
-- | Convert a list of Pandoc blocks to ICML.
|
-- | Convert a list of Pandoc blocks to ICML.
|
||||||
blocksToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m Doc
|
blocksToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m (Doc Text)
|
||||||
blocksToICML opts style lst = do
|
blocksToICML opts style lst = do
|
||||||
docs <- mapM (blockToICML opts style) lst
|
docs <- mapM (blockToICML opts style) lst
|
||||||
return $ intersperseBrs docs
|
return $ intersperseBrs docs
|
||||||
|
|
||||||
-- | Convert a Pandoc block element to ICML.
|
-- | Convert a Pandoc block element to ICML.
|
||||||
blockToICML :: PandocMonad m => WriterOptions -> Style -> Block -> WS m Doc
|
blockToICML :: PandocMonad m => WriterOptions -> Style -> Block -> WS m (Doc Text)
|
||||||
blockToICML opts style (Plain lst) = parStyle opts style lst
|
blockToICML opts style (Plain lst) = parStyle opts style lst
|
||||||
-- title beginning with fig: indicates that the image is a figure
|
-- title beginning with fig: indicates that the image is a figure
|
||||||
blockToICML opts style (Para img@[Image _ txt (_,'f':'i':'g':':':_)]) = do
|
blockToICML opts style (Para img@[Image _ txt (_,'f':'i':'g':':':_)]) = do
|
||||||
|
@ -375,7 +372,7 @@ blockToICML opts style (Div (_, _, kvs) lst) =
|
||||||
blockToICML _ _ Null = return empty
|
blockToICML _ _ Null = return empty
|
||||||
|
|
||||||
-- | Convert a list of lists of blocks to ICML list items.
|
-- | Convert a list of lists of blocks to ICML list items.
|
||||||
listItemsToICML :: PandocMonad m => WriterOptions -> String -> Style -> Maybe ListAttributes -> [[Block]] -> WS m Doc
|
listItemsToICML :: PandocMonad m => WriterOptions -> String -> Style -> Maybe ListAttributes -> [[Block]] -> WS m (Doc Text)
|
||||||
listItemsToICML _ _ _ _ [] = return empty
|
listItemsToICML _ _ _ _ [] = return empty
|
||||||
listItemsToICML opts listType style attribs (first:rest) = do
|
listItemsToICML opts listType style attribs (first:rest) = do
|
||||||
st <- get
|
st <- get
|
||||||
|
@ -390,7 +387,7 @@ listItemsToICML opts listType style attribs (first:rest) = do
|
||||||
return $ intersperseBrs docs
|
return $ intersperseBrs docs
|
||||||
|
|
||||||
-- | Convert a list of blocks to ICML list items.
|
-- | Convert a list of blocks to ICML list items.
|
||||||
listItemToICML :: PandocMonad m => WriterOptions -> Style -> Bool-> Maybe ListAttributes -> [Block] -> WS m Doc
|
listItemToICML :: PandocMonad m => WriterOptions -> Style -> Bool-> Maybe ListAttributes -> [Block] -> WS m (Doc Text)
|
||||||
listItemToICML opts style isFirst attribs item =
|
listItemToICML opts style isFirst attribs item =
|
||||||
let makeNumbStart (Just (beginsWith, numbStl, _)) =
|
let makeNumbStart (Just (beginsWith, numbStl, _)) =
|
||||||
let doN DefaultStyle = []
|
let doN DefaultStyle = []
|
||||||
|
@ -416,7 +413,7 @@ listItemToICML opts style isFirst attribs item =
|
||||||
return $ intersperseBrs (f : r)
|
return $ intersperseBrs (f : r)
|
||||||
else blocksToICML opts stl' item
|
else blocksToICML opts stl' item
|
||||||
|
|
||||||
definitionListItemToICML :: PandocMonad m => WriterOptions -> Style -> ([Inline],[[Block]]) -> WS m Doc
|
definitionListItemToICML :: PandocMonad m => WriterOptions -> Style -> ([Inline],[[Block]]) -> WS m (Doc Text)
|
||||||
definitionListItemToICML opts style (term,defs) = do
|
definitionListItemToICML opts style (term,defs) = do
|
||||||
term' <- parStyle opts (defListTermName:style) term
|
term' <- parStyle opts (defListTermName:style) term
|
||||||
defs' <- mapM (blocksToICML opts (defListDefName:style)) defs
|
defs' <- mapM (blocksToICML opts (defListDefName:style)) defs
|
||||||
|
@ -424,11 +421,11 @@ definitionListItemToICML opts style (term,defs) = do
|
||||||
|
|
||||||
|
|
||||||
-- | Convert a list of inline elements to ICML.
|
-- | Convert a list of inline elements to ICML.
|
||||||
inlinesToICML :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m Doc
|
inlinesToICML :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m (Doc Text)
|
||||||
inlinesToICML opts style lst = vcat `fmap` mapM (inlineToICML opts style) (mergeStrings opts lst)
|
inlinesToICML opts style lst = vcat `fmap` mapM (inlineToICML opts style) (mergeStrings opts lst)
|
||||||
|
|
||||||
-- | Convert an inline element to ICML.
|
-- | Convert an inline element to ICML.
|
||||||
inlineToICML :: PandocMonad m => WriterOptions -> Style -> Inline -> WS m Doc
|
inlineToICML :: PandocMonad m => WriterOptions -> Style -> Inline -> WS m (Doc Text)
|
||||||
inlineToICML _ style (Str str) = charStyle style $ text $ escapeStringForXML str
|
inlineToICML _ style (Str str) = charStyle style $ text $ escapeStringForXML str
|
||||||
inlineToICML opts style (Emph lst) = inlinesToICML opts (emphName:style) lst
|
inlineToICML opts style (Emph lst) = inlinesToICML opts (emphName:style) lst
|
||||||
inlineToICML opts style (Strong lst) = inlinesToICML opts (strongName:style) lst
|
inlineToICML opts style (Strong lst) = inlinesToICML opts (strongName:style) lst
|
||||||
|
@ -451,7 +448,7 @@ inlineToICML opts style SoftBreak =
|
||||||
inlineToICML _ style LineBreak = charStyle style $ text lineSeparator
|
inlineToICML _ style LineBreak = charStyle style $ text lineSeparator
|
||||||
inlineToICML opts style (Math mt str) =
|
inlineToICML opts style (Math mt str) =
|
||||||
lift (texMathToInlines mt str) >>=
|
lift (texMathToInlines mt str) >>=
|
||||||
(fmap cat . mapM (inlineToICML opts style))
|
(fmap mconcat . mapM (inlineToICML opts style))
|
||||||
inlineToICML _ _ il@(RawInline f str)
|
inlineToICML _ _ il@(RawInline f str)
|
||||||
| f == Format "icml" = return $ text str
|
| f == Format "icml" = return $ text str
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
|
@ -474,7 +471,7 @@ inlineToICML opts style (Span (_, _, kvs) lst) =
|
||||||
in inlinesToICML opts (dynamicStyle <> style) lst
|
in inlinesToICML opts (dynamicStyle <> style) lst
|
||||||
|
|
||||||
-- | Convert a list of block elements to an ICML footnote.
|
-- | Convert a list of block elements to an ICML footnote.
|
||||||
footnoteToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m Doc
|
footnoteToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m (Doc Text)
|
||||||
footnoteToICML opts style lst =
|
footnoteToICML opts style lst =
|
||||||
let insertTab (Para ls) = blockToICML opts (footnoteName:style) $ Para $ Str "\t":ls
|
let insertTab (Para ls) = blockToICML opts (footnoteName:style) $ Para $ Str "\t":ls
|
||||||
insertTab block = blockToICML opts (footnoteName:style) block
|
insertTab block = blockToICML opts (footnoteName:style) block
|
||||||
|
@ -500,11 +497,11 @@ mergeStrings opts = mergeStrings' . map spaceToStr
|
||||||
mergeStrings' [] = []
|
mergeStrings' [] = []
|
||||||
|
|
||||||
-- | Intersperse line breaks
|
-- | Intersperse line breaks
|
||||||
intersperseBrs :: [Doc] -> Doc
|
intersperseBrs :: [Doc Text] -> Doc Text
|
||||||
intersperseBrs = vcat . intersperse (selfClosingTag "Br" []) . filter (not . isEmpty)
|
intersperseBrs = vcat . intersperse (selfClosingTag "Br" []) . filter (not . isEmpty)
|
||||||
|
|
||||||
-- | Wrap a list of inline elements in an ICML Paragraph Style
|
-- | Wrap a list of inline elements in an ICML Paragraph Style
|
||||||
parStyle :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m Doc
|
parStyle :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m (Doc Text)
|
||||||
parStyle opts style lst =
|
parStyle opts style lst =
|
||||||
let slipIn x y = if null y
|
let slipIn x y = if null y
|
||||||
then x
|
then x
|
||||||
|
@ -528,7 +525,7 @@ parStyle opts style lst =
|
||||||
state $ \st -> (cont, st{ blockStyles = Set.insert stlStr $ blockStyles st })
|
state $ \st -> (cont, st{ blockStyles = Set.insert stlStr $ blockStyles st })
|
||||||
|
|
||||||
-- | Wrap a Doc in an ICML Character Style.
|
-- | Wrap a Doc in an ICML Character Style.
|
||||||
charStyle :: PandocMonad m => Style -> Doc -> WS m Doc
|
charStyle :: PandocMonad m => Style -> Doc Text -> WS m (Doc Text)
|
||||||
charStyle style content =
|
charStyle style content =
|
||||||
let (stlStr, attrs) = styleToStrAttr style
|
let (stlStr, attrs) = styleToStrAttr style
|
||||||
doc = inTags True "CharacterStyleRange" attrs $ inTagsSimple "Content" $ flush content
|
doc = inTags True "CharacterStyleRange" attrs $ inTagsSimple "Content" $ flush content
|
||||||
|
@ -550,7 +547,7 @@ styleToStrAttr style =
|
||||||
in (stlStr, attrs)
|
in (stlStr, attrs)
|
||||||
|
|
||||||
-- | Assemble an ICML Image.
|
-- | Assemble an ICML Image.
|
||||||
imageICML :: PandocMonad m => WriterOptions -> Style -> Attr -> Target -> WS m Doc
|
imageICML :: PandocMonad m => WriterOptions -> Style -> Attr -> Target -> WS m (Doc Text)
|
||||||
imageICML opts style attr (src, _) = do
|
imageICML opts style attr (src, _) = do
|
||||||
imgS <- catchError
|
imgS <- catchError
|
||||||
(do (img, _) <- P.fetchItem src
|
(do (img, _) <- P.fetchItem src
|
||||||
|
|
|
@ -33,7 +33,7 @@ import qualified Data.Text as T
|
||||||
import Data.Aeson as Aeson
|
import Data.Aeson as Aeson
|
||||||
import qualified Text.Pandoc.UTF8 as UTF8
|
import qualified Text.Pandoc.UTF8 as UTF8
|
||||||
import Text.Pandoc.Shared (safeRead, isURI)
|
import Text.Pandoc.Shared (safeRead, isURI)
|
||||||
import Text.Pandoc.Writers.Shared (metaToJSON')
|
import Text.Pandoc.Writers.Shared (metaToContext')
|
||||||
import Text.Pandoc.Writers.Markdown (writeMarkdown)
|
import Text.Pandoc.Writers.Markdown (writeMarkdown)
|
||||||
import qualified Data.Text.Encoding as TE
|
import qualified Data.Text.Encoding as TE
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
@ -73,9 +73,10 @@ pandocToNotebook opts (Pandoc meta blocks) = do
|
||||||
Just z -> (4, z)
|
Just z -> (4, z)
|
||||||
Nothing -> (4, 5)
|
Nothing -> (4, 5)
|
||||||
_ -> (4, 5) -- write as v4.5
|
_ -> (4, 5) -- write as v4.5
|
||||||
metadata' <- metaToJSON' blockWriter inlineWriter $
|
metadata' <- toJSON <$> metaToContext' blockWriter inlineWriter
|
||||||
B.deleteMeta "nbformat" $
|
(B.deleteMeta "nbformat" $
|
||||||
B.deleteMeta "nbformat_minor" $ jupyterMeta
|
B.deleteMeta "nbformat_minor" $
|
||||||
|
jupyterMeta)
|
||||||
-- convert from a Value (JSON object) to a M.Map Text Value:
|
-- convert from a Value (JSON object) to a M.Map Text Value:
|
||||||
let metadata = case fromJSON metadata' of
|
let metadata = case fromJSON metadata' of
|
||||||
Error _ -> mempty -- TODO warning here? shouldn't happen
|
Error _ -> mempty -- TODO warning here? shouldn't happen
|
||||||
|
@ -109,7 +110,7 @@ extractCells opts (Div (_id,classes,kvs) xs : bs)
|
||||||
source <- writeMarkdown opts{ writerTemplate = Nothing } newdoc
|
source <- writeMarkdown opts{ writerTemplate = Nothing } newdoc
|
||||||
(Cell{
|
(Cell{
|
||||||
cellType = Markdown
|
cellType = Markdown
|
||||||
, cellSource = Source $ breakLines source
|
, cellSource = Source $ breakLines $ T.stripEnd source
|
||||||
, cellMetadata = meta
|
, cellMetadata = meta
|
||||||
, cellAttachments = if M.null attachments
|
, cellAttachments = if M.null attachments
|
||||||
then Nothing
|
then Nothing
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{- |
|
{- |
|
||||||
Module : Text.Pandoc.Writers.JATS
|
Module : Text.Pandoc.Writers.JATS
|
||||||
|
@ -23,6 +24,7 @@ import Data.List (partition, isPrefixOf)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
|
import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
|
||||||
|
import qualified Data.Text as T
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
|
@ -31,9 +33,10 @@ import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.MIME (getMimeType)
|
import Text.Pandoc.MIME (getMimeType)
|
||||||
import Text.Pandoc.Walk (walk)
|
import Text.Pandoc.Walk (walk)
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
|
import Text.DocTemplates (Context(..), Val(..), TemplateTarget(..))
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Pandoc.XML
|
import Text.Pandoc.XML
|
||||||
|
@ -44,7 +47,7 @@ data JATSVersion = JATS1_1
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
data JATSState = JATSState
|
data JATSState = JATSState
|
||||||
{ jatsNotes :: [(Int, Doc)] }
|
{ jatsNotes :: [(Int, Doc Text)] }
|
||||||
|
|
||||||
type JATS a = StateT JATSState (ReaderT JATSVersion a)
|
type JATS a = StateT JATSState (ReaderT JATSVersion a)
|
||||||
|
|
||||||
|
@ -65,54 +68,56 @@ docToJATS opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
-- The numbering here follows LaTeX's internal numbering
|
-- The numbering here follows LaTeX's internal numbering
|
||||||
let startLvl = case writerTopLevelDivision opts of
|
let startLvl = case writerTopLevelDivision opts of
|
||||||
TopLevelPart -> -1
|
TopLevelPart -> -1
|
||||||
TopLevelChapter -> 0
|
TopLevelChapter -> 0
|
||||||
TopLevelSection -> 1
|
TopLevelSection -> 1
|
||||||
TopLevelDefault -> 1
|
TopLevelDefault -> 1
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap (render' . vcat) .
|
(fmap vcat .
|
||||||
mapM (elementToJATS opts startLvl) .
|
mapM (elementToJATS opts startLvl) .
|
||||||
hierarchicalize)
|
hierarchicalize)
|
||||||
(fmap render' . inlinesToJATS opts)
|
(fmap chomp . inlinesToJATS opts)
|
||||||
meta
|
meta
|
||||||
main <- (render' . vcat) <$>
|
main <- vcat <$> mapM (elementToJATS opts startLvl) elements
|
||||||
mapM (elementToJATS opts startLvl) elements
|
|
||||||
notes <- reverse . map snd <$> gets jatsNotes
|
notes <- reverse . map snd <$> gets jatsNotes
|
||||||
backs <- mapM (elementToJATS opts startLvl) backElements
|
backs <- mapM (elementToJATS opts startLvl) backElements
|
||||||
let fns = if null notes
|
let fns = if null notes
|
||||||
then mempty
|
then mempty
|
||||||
else inTagsIndented "fn-group" $ vcat notes
|
else inTagsIndented "fn-group" $ vcat notes
|
||||||
let back = render' $ vcat backs $$ fns
|
let back = vcat backs $$ fns
|
||||||
let date = case getField "date" metadata -- an object
|
let date =
|
||||||
`mplus`
|
case getField "date" metadata of
|
||||||
(getField "date" metadata >>= parseDate) of
|
Nothing -> NullVal
|
||||||
Nothing -> mempty
|
Just (SimpleVal (x :: Doc Text)) ->
|
||||||
|
case parseDate (T.unpack $ toText x) of
|
||||||
|
Nothing -> NullVal
|
||||||
Just day ->
|
Just day ->
|
||||||
let (y,m,d) = toGregorian day
|
let (y,m,d) = toGregorian day
|
||||||
in M.insert ("year" :: String) (show y)
|
in MapVal $ Context
|
||||||
$ M.insert "month" (show m)
|
$ M.insert ("year" :: Text) (SimpleVal $ text $ show y)
|
||||||
$ M.insert "day" (show d)
|
$ M.insert "month" (SimpleVal $ text $ show m)
|
||||||
|
$ M.insert "day" (SimpleVal $ text $ show d)
|
||||||
$ M.insert "iso-8601"
|
$ M.insert "iso-8601"
|
||||||
(formatTime defaultTimeLocale "%F" day)
|
(SimpleVal $ text $
|
||||||
|
formatTime defaultTimeLocale "%F" day)
|
||||||
$ mempty
|
$ mempty
|
||||||
|
Just x -> x
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "back" back
|
$ defField "back" back
|
||||||
$ resetField ("date" :: String) date
|
$ resetField "date" date
|
||||||
$ defField "mathml" (case writerHTMLMathMethod opts of
|
$ defField "mathml" (case writerHTMLMathMethod opts of
|
||||||
MathML -> True
|
MathML -> True
|
||||||
_ -> False) metadata
|
_ -> False) metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
(if writerPreferAscii opts then toEntities else id) $
|
(if writerPreferAscii opts then fmap toEntities else id) $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Convert an Element to JATS.
|
-- | Convert an Element to JATS.
|
||||||
elementToJATS :: PandocMonad m => WriterOptions -> Int -> Element -> JATS m Doc
|
elementToJATS :: PandocMonad m => WriterOptions -> Int -> Element -> JATS m (Doc Text)
|
||||||
elementToJATS opts _ (Blk block) = blockToJATS opts block
|
elementToJATS opts _ (Blk block) = blockToJATS opts block
|
||||||
elementToJATS opts lvl (Sec _ _num (id',_,kvs) title elements) = do
|
elementToJATS opts lvl (Sec _ _num (id',_,kvs) title elements) = do
|
||||||
let idAttr = [("id", writerIdentifierPrefix opts ++ id') | not (null id')]
|
let idAttr = [("id", writerIdentifierPrefix opts ++ id') | not (null id')]
|
||||||
|
@ -124,14 +129,14 @@ elementToJATS opts lvl (Sec _ _num (id',_,kvs) title elements) = do
|
||||||
inTagsSimple "title" title' $$ vcat contents
|
inTagsSimple "title" title' $$ vcat contents
|
||||||
|
|
||||||
-- | Convert a list of Pandoc blocks to JATS.
|
-- | Convert a list of Pandoc blocks to JATS.
|
||||||
blocksToJATS :: PandocMonad m => WriterOptions -> [Block] -> JATS m Doc
|
blocksToJATS :: PandocMonad m => WriterOptions -> [Block] -> JATS m (Doc Text)
|
||||||
blocksToJATS = wrappedBlocksToJATS (const False)
|
blocksToJATS = wrappedBlocksToJATS (const False)
|
||||||
|
|
||||||
wrappedBlocksToJATS :: PandocMonad m
|
wrappedBlocksToJATS :: PandocMonad m
|
||||||
=> (Block -> Bool)
|
=> (Block -> Bool)
|
||||||
-> WriterOptions
|
-> WriterOptions
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> JATS m Doc
|
-> JATS m (Doc Text)
|
||||||
wrappedBlocksToJATS needsWrap opts =
|
wrappedBlocksToJATS needsWrap opts =
|
||||||
fmap vcat . mapM wrappedBlockToJATS
|
fmap vcat . mapM wrappedBlockToJATS
|
||||||
where
|
where
|
||||||
|
@ -150,13 +155,13 @@ plainToPara x = x
|
||||||
-- | Convert a list of pairs of terms and definitions into a list of
|
-- | Convert a list of pairs of terms and definitions into a list of
|
||||||
-- JATS varlistentrys.
|
-- JATS varlistentrys.
|
||||||
deflistItemsToJATS :: PandocMonad m
|
deflistItemsToJATS :: PandocMonad m
|
||||||
=> WriterOptions -> [([Inline],[[Block]])] -> JATS m Doc
|
=> WriterOptions -> [([Inline],[[Block]])] -> JATS m (Doc Text)
|
||||||
deflistItemsToJATS opts items =
|
deflistItemsToJATS opts items =
|
||||||
vcat <$> mapM (uncurry (deflistItemToJATS opts)) items
|
vcat <$> mapM (uncurry (deflistItemToJATS opts)) items
|
||||||
|
|
||||||
-- | Convert a term and a list of blocks into a JATS varlistentry.
|
-- | Convert a term and a list of blocks into a JATS varlistentry.
|
||||||
deflistItemToJATS :: PandocMonad m
|
deflistItemToJATS :: PandocMonad m
|
||||||
=> WriterOptions -> [Inline] -> [[Block]] -> JATS m Doc
|
=> WriterOptions -> [Inline] -> [[Block]] -> JATS m (Doc Text)
|
||||||
deflistItemToJATS opts term defs = do
|
deflistItemToJATS opts term defs = do
|
||||||
term' <- inlinesToJATS opts term
|
term' <- inlinesToJATS opts term
|
||||||
def' <- wrappedBlocksToJATS (not . isPara)
|
def' <- wrappedBlocksToJATS (not . isPara)
|
||||||
|
@ -168,7 +173,7 @@ deflistItemToJATS opts term defs = do
|
||||||
|
|
||||||
-- | Convert a list of lists of blocks to a list of JATS list items.
|
-- | Convert a list of lists of blocks to a list of JATS list items.
|
||||||
listItemsToJATS :: PandocMonad m
|
listItemsToJATS :: PandocMonad m
|
||||||
=> WriterOptions -> Maybe [String] -> [[Block]] -> JATS m Doc
|
=> WriterOptions -> Maybe [String] -> [[Block]] -> JATS m (Doc Text)
|
||||||
listItemsToJATS opts markers items =
|
listItemsToJATS opts markers items =
|
||||||
case markers of
|
case markers of
|
||||||
Nothing -> vcat <$> mapM (listItemToJATS opts Nothing) items
|
Nothing -> vcat <$> mapM (listItemToJATS opts Nothing) items
|
||||||
|
@ -176,7 +181,7 @@ listItemsToJATS opts markers items =
|
||||||
|
|
||||||
-- | Convert a list of blocks into a JATS list item.
|
-- | Convert a list of blocks into a JATS list item.
|
||||||
listItemToJATS :: PandocMonad m
|
listItemToJATS :: PandocMonad m
|
||||||
=> WriterOptions -> Maybe String -> [Block] -> JATS m Doc
|
=> WriterOptions -> Maybe String -> [Block] -> JATS m (Doc Text)
|
||||||
listItemToJATS opts mbmarker item = do
|
listItemToJATS opts mbmarker item = do
|
||||||
contents <- wrappedBlocksToJATS (not . isParaOrList) opts
|
contents <- wrappedBlocksToJATS (not . isParaOrList) opts
|
||||||
(walk demoteHeaderAndRefs item)
|
(walk demoteHeaderAndRefs item)
|
||||||
|
@ -218,7 +223,7 @@ codeAttr (ident,classes,kvs) = (lang, attr)
|
||||||
lang = languageFor classes
|
lang = languageFor classes
|
||||||
|
|
||||||
-- | Convert a Pandoc block element to JATS.
|
-- | Convert a Pandoc block element to JATS.
|
||||||
blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m Doc
|
blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m (Doc Text)
|
||||||
blockToJATS _ Null = return empty
|
blockToJATS _ Null = return empty
|
||||||
-- Bibliography reference:
|
-- Bibliography reference:
|
||||||
blockToJATS opts (Div ('r':'e':'f':'-':_,_,_) [Para lst]) =
|
blockToJATS opts (Div ('r':'e':'f':'-':_,_,_) [Para lst]) =
|
||||||
|
@ -341,7 +346,7 @@ tableRowToJATS :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> Bool
|
-> Bool
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> JATS m Doc
|
-> JATS m (Doc Text)
|
||||||
tableRowToJATS opts isHeader cols =
|
tableRowToJATS opts isHeader cols =
|
||||||
(inTagsIndented "tr" . vcat) <$> mapM (tableItemToJATS opts isHeader) cols
|
(inTagsIndented "tr" . vcat) <$> mapM (tableItemToJATS opts isHeader) cols
|
||||||
|
|
||||||
|
@ -349,7 +354,7 @@ tableItemToJATS :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> Bool
|
-> Bool
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> JATS m Doc
|
-> JATS m (Doc Text)
|
||||||
tableItemToJATS opts isHeader [Plain item] =
|
tableItemToJATS opts isHeader [Plain item] =
|
||||||
inTags False (if isHeader then "th" else "td") [] <$>
|
inTags False (if isHeader then "th" else "td") [] <$>
|
||||||
inlinesToJATS opts item
|
inlinesToJATS opts item
|
||||||
|
@ -358,7 +363,7 @@ tableItemToJATS opts isHeader item =
|
||||||
mapM (blockToJATS opts) item
|
mapM (blockToJATS opts) item
|
||||||
|
|
||||||
-- | Convert a list of inline elements to JATS.
|
-- | Convert a list of inline elements to JATS.
|
||||||
inlinesToJATS :: PandocMonad m => WriterOptions -> [Inline] -> JATS m Doc
|
inlinesToJATS :: PandocMonad m => WriterOptions -> [Inline] -> JATS m (Doc Text)
|
||||||
inlinesToJATS opts lst = hcat <$> mapM (inlineToJATS opts) (fixCitations lst)
|
inlinesToJATS opts lst = hcat <$> mapM (inlineToJATS opts) (fixCitations lst)
|
||||||
where
|
where
|
||||||
fixCitations [] = []
|
fixCitations [] = []
|
||||||
|
@ -374,7 +379,7 @@ inlinesToJATS opts lst = hcat <$> mapM (inlineToJATS opts) (fixCitations lst)
|
||||||
fixCitations (x:xs) = x : fixCitations xs
|
fixCitations (x:xs) = x : fixCitations xs
|
||||||
|
|
||||||
-- | Convert an inline element to JATS.
|
-- | Convert an inline element to JATS.
|
||||||
inlineToJATS :: PandocMonad m => WriterOptions -> Inline -> JATS m Doc
|
inlineToJATS :: PandocMonad m => WriterOptions -> Inline -> JATS m (Doc Text)
|
||||||
inlineToJATS _ (Str str) = return $ text $ escapeStringForXML str
|
inlineToJATS _ (Str str) = return $ text $ escapeStringForXML str
|
||||||
inlineToJATS opts (Emph lst) =
|
inlineToJATS opts (Emph lst) =
|
||||||
inTagsSimple "italic" <$> inlinesToJATS opts lst
|
inTagsSimple "italic" <$> inlinesToJATS opts lst
|
||||||
|
|
|
@ -27,7 +27,7 @@ import Text.Pandoc.Options (WriterOptions (writerTemplate))
|
||||||
import Text.Pandoc.Shared (blocksToInlines, linesToPara)
|
import Text.Pandoc.Shared (blocksToInlines, linesToPara)
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Math (texMathToInlines)
|
import Text.Pandoc.Writers.Math (texMathToInlines)
|
||||||
import Text.Pandoc.Writers.Shared (metaToJSON, defField)
|
import Text.Pandoc.Writers.Shared (metaToContext, defField)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
data WriterState = WriterState
|
data WriterState = WriterState
|
||||||
|
@ -53,7 +53,7 @@ writeJira opts document =
|
||||||
pandocToJira :: PandocMonad m
|
pandocToJira :: PandocMonad m
|
||||||
=> WriterOptions -> Pandoc -> JiraWriter m Text
|
=> WriterOptions -> Pandoc -> JiraWriter m Text
|
||||||
pandocToJira opts (Pandoc meta blocks) = do
|
pandocToJira opts (Pandoc meta blocks) = do
|
||||||
metadata <- metaToJSON opts (blockListToJira opts)
|
metadata <- metaToContext opts (blockListToJira opts)
|
||||||
(inlineListToJira opts) meta
|
(inlineListToJira opts) meta
|
||||||
body <- blockListToJira opts blocks
|
body <- blockListToJira opts blocks
|
||||||
notes <- gets $ T.intercalate "\n" . reverse . stNotes
|
notes <- gets $ T.intercalate "\n" . reverse . stNotes
|
||||||
|
|
|
@ -21,7 +21,6 @@ import Prelude
|
||||||
import Control.Applicative ((<|>))
|
import Control.Applicative ((<|>))
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
import Data.Monoid (Any(..))
|
import Data.Monoid (Any(..))
|
||||||
import Data.Aeson (object, (.=))
|
|
||||||
import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isSpace,
|
import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isSpace,
|
||||||
isPunctuation, ord, toLower)
|
isPunctuation, ord, toLower)
|
||||||
import Data.List (foldl', intercalate, intersperse, nubBy,
|
import Data.List (foldl', intercalate, intersperse, nubBy,
|
||||||
|
@ -39,10 +38,11 @@ import Text.Pandoc.Highlighting (formatLaTeXBlock, formatLaTeXInline, highlight,
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Slides
|
import Text.Pandoc.Slides
|
||||||
import Text.Pandoc.Templates
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
|
import Text.DocTemplates (Val(..), Context(..))
|
||||||
import Text.Pandoc.Walk
|
import Text.Pandoc.Walk
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
|
@ -56,7 +56,7 @@ data WriterState =
|
||||||
, stInMinipage :: Bool -- true if in minipage
|
, stInMinipage :: Bool -- true if in minipage
|
||||||
, stInHeading :: Bool -- true if in a section heading
|
, stInHeading :: Bool -- true if in a section heading
|
||||||
, stInItem :: Bool -- true if in \item[..]
|
, stInItem :: Bool -- true if in \item[..]
|
||||||
, stNotes :: [Doc] -- notes in a minipage
|
, stNotes :: [Doc Text] -- notes in a minipage
|
||||||
, stOLLevel :: Int -- level of ordered list nesting
|
, stOLLevel :: Int -- level of ordered list nesting
|
||||||
, stOptions :: WriterOptions -- writer options, so they don't have to be parameter
|
, stOptions :: WriterOptions -- writer options, so they don't have to be parameter
|
||||||
, stVerbInNote :: Bool -- true if document has verbatim text in note
|
, stVerbInNote :: Bool -- true if document has verbatim text in note
|
||||||
|
@ -133,11 +133,9 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText options == WrapAuto
|
let colwidth = if writerWrapText options == WrapAuto
|
||||||
then Just $ writerColumns options
|
then Just $ writerColumns options
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext options
|
||||||
render' = render colwidth
|
blockListToLaTeX
|
||||||
metadata <- metaToJSON options
|
(fmap chomp . inlineListToLaTeX)
|
||||||
(fmap render' . blockListToLaTeX)
|
|
||||||
(fmap render' . inlineListToLaTeX)
|
|
||||||
meta
|
meta
|
||||||
let chaptersClasses = ["memoir","book","report","scrreprt","scrbook","extreport","extbook","tufte-book"]
|
let chaptersClasses = ["memoir","book","report","scrreprt","scrbook","extreport","extbook","tufte-book"]
|
||||||
let frontmatterClasses = ["memoir","book","scrbook","extbook","tufte-book"]
|
let frontmatterClasses = ["memoir","book","scrbook","extbook","tufte-book"]
|
||||||
|
@ -154,7 +152,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
_ -> "article"
|
_ -> "article"
|
||||||
when (documentClass `elem` chaptersClasses) $
|
when (documentClass `elem` chaptersClasses) $
|
||||||
modify $ \s -> s{ stHasChapters = True }
|
modify $ \s -> s{ stHasChapters = True }
|
||||||
case T.toLower <$> getField "csquotes" metadata of
|
case T.toLower . render Nothing <$> getField "csquotes" metadata of
|
||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
Just "false" -> return ()
|
Just "false" -> return ()
|
||||||
Just _ -> modify $ \s -> s{stCsquotes = True}
|
Just _ -> modify $ \s -> s{stCsquotes = True}
|
||||||
|
@ -167,23 +165,26 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
then toSlides blocks''
|
then toSlides blocks''
|
||||||
else return blocks''
|
else return blocks''
|
||||||
body <- mapM (elementToLaTeX options) $ hierarchicalize blocks'''
|
body <- mapM (elementToLaTeX options) $ hierarchicalize blocks'''
|
||||||
(biblioTitle :: Text) <- render' <$> inlineListToLaTeX lastHeader
|
biblioTitle <- inlineListToLaTeX lastHeader
|
||||||
let main = render' $ vsep body
|
let main = vsep body
|
||||||
st <- get
|
st <- get
|
||||||
titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
|
titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
|
||||||
authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
|
authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
|
||||||
docLangs <- catMaybes <$>
|
docLangs <- catMaybes <$>
|
||||||
mapM (toLang . Just) (ordNub (query (extract "lang") blocks))
|
mapM (toLang . Just) (ordNub (query (extract "lang") blocks))
|
||||||
let hasStringValue x = isJust (getField x metadata :: Maybe String)
|
let hasStringValue x = isJust (getField x metadata :: Maybe (Doc Text))
|
||||||
let geometryFromMargins = intercalate [','] $ mapMaybe (\(x,y) ->
|
let geometryFromMargins = mconcat $ intersperse ("," :: Doc Text) $
|
||||||
((x ++ "=") ++) <$> getField y metadata)
|
mapMaybe (\(x,y) ->
|
||||||
|
((x <> "=") <>) <$> getField y metadata)
|
||||||
[("lmargin","margin-left")
|
[("lmargin","margin-left")
|
||||||
,("rmargin","margin-right")
|
,("rmargin","margin-right")
|
||||||
,("tmargin","margin-top")
|
,("tmargin","margin-top")
|
||||||
,("bmargin","margin-bottom")
|
,("bmargin","margin-bottom")
|
||||||
]
|
]
|
||||||
let toPolyObj lang = object [ "name" .= T.pack name
|
let toPolyObj :: Lang -> Val (Doc Text)
|
||||||
, "options" .= T.pack opts ]
|
toPolyObj lang = MapVal $ Context $
|
||||||
|
M.fromList [ ("name" , SimpleVal $ text name)
|
||||||
|
, ("options" , SimpleVal $ text opts) ]
|
||||||
where
|
where
|
||||||
(name, opts) = toPolyglossia lang
|
(name, opts) = toPolyglossia lang
|
||||||
mblang <- toLang $ case getLang options meta of
|
mblang <- toLang $ case getLang options meta of
|
||||||
|
@ -195,14 +196,16 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
let dirs = query (extract "dir") blocks
|
let dirs = query (extract "dir") blocks
|
||||||
|
|
||||||
let context = defField "toc" (writerTableOfContents options) $
|
let context = defField "toc" (writerTableOfContents options) $
|
||||||
defField "toc-depth" (show (writerTOCDepth options -
|
defField "toc-depth" (T.pack . show $
|
||||||
|
(writerTOCDepth options -
|
||||||
if stHasChapters st
|
if stHasChapters st
|
||||||
then 1
|
then 1
|
||||||
else 0)) $
|
else 0)) $
|
||||||
defField "body" main $
|
defField "body" main $
|
||||||
defField "title-meta" titleMeta $
|
defField "title-meta" (T.pack titleMeta) $
|
||||||
defField "author-meta" (intercalate "; " authorsMeta) $
|
defField "author-meta"
|
||||||
defField "documentclass" documentClass $
|
(T.pack $ intercalate "; " authorsMeta) $
|
||||||
|
defField "documentclass" (T.pack documentClass) $
|
||||||
defField "verbatim-in-note" (stVerbInNote st) $
|
defField "verbatim-in-note" (stVerbInNote st) $
|
||||||
defField "tables" (stTable st) $
|
defField "tables" (stTable st) $
|
||||||
defField "strikeout" (stStrikeout st) $
|
defField "strikeout" (stStrikeout st) $
|
||||||
|
@ -218,7 +221,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
then case writerHighlightStyle options of
|
then case writerHighlightStyle options of
|
||||||
Just sty ->
|
Just sty ->
|
||||||
defField "highlighting-macros"
|
defField "highlighting-macros"
|
||||||
(styleToLaTeX sty)
|
(T.stripEnd $ styleToLaTeX sty)
|
||||||
Nothing -> id
|
Nothing -> id
|
||||||
else id) $
|
else id) $
|
||||||
(case writerCiteMethod options of
|
(case writerCiteMethod options of
|
||||||
|
@ -232,23 +235,28 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
"filecolor"]) $
|
"filecolor"]) $
|
||||||
(if null dirs
|
(if null dirs
|
||||||
then id
|
then id
|
||||||
else defField "dir" ("ltr" :: String)) $
|
else defField "dir" ("ltr" :: Text)) $
|
||||||
defField "section-titles" True $
|
defField "section-titles" True $
|
||||||
defField "geometry" geometryFromMargins $
|
defField "geometry" geometryFromMargins $
|
||||||
(case getField "papersize" metadata of
|
(case T.unpack . render Nothing <$>
|
||||||
|
getField "papersize" metadata of
|
||||||
-- uppercase a4, a5, etc.
|
-- uppercase a4, a5, etc.
|
||||||
Just (('A':d:ds) :: String)
|
Just (('A':d:ds) :: String)
|
||||||
| all isDigit (d:ds) -> resetField "papersize"
|
| all isDigit (d:ds) -> resetField "papersize"
|
||||||
(('a':d:ds) :: String)
|
(T.pack ('a':d:ds))
|
||||||
_ -> id)
|
_ -> id)
|
||||||
metadata
|
metadata
|
||||||
let context' =
|
let context' =
|
||||||
-- note: lang is used in some conditionals in the template,
|
-- note: lang is used in some conditionals in the template,
|
||||||
-- so we need to set it if we have any babel/polyglossia:
|
-- so we need to set it if we have any babel/polyglossia:
|
||||||
maybe id (defField "lang" . renderLang) mblang
|
maybe id (\l -> defField "lang"
|
||||||
$ maybe id (defField "babel-lang" . toBabel) mblang
|
((text $ renderLang l) :: Doc Text)) mblang
|
||||||
$ defField "babel-otherlangs" (map toBabel docLangs)
|
$ maybe id (\l -> defField "babel-lang"
|
||||||
$ defField "babel-newcommands" (concatMap (\(poly, babel) ->
|
((text $ toBabel l) :: Doc Text)) mblang
|
||||||
|
$ defField "babel-otherlangs"
|
||||||
|
(map ((text . toBabel) :: Lang -> Doc Text) docLangs)
|
||||||
|
$ defField "babel-newcommands" (vcat $
|
||||||
|
map (\(poly, babel) -> (text :: String -> Doc Text) $
|
||||||
-- \textspanish and \textgalician are already used by babel
|
-- \textspanish and \textgalician are already used by babel
|
||||||
-- save them as \oritext... and let babel use that
|
-- save them as \oritext... and let babel use that
|
||||||
if poly `elem` ["spanish", "galician"]
|
if poly `elem` ["spanish", "galician"]
|
||||||
|
@ -258,14 +266,14 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
++ poly ++ "}}\n" ++
|
++ poly ++ "}}\n" ++
|
||||||
"\\AddBabelHook{" ++ poly ++ "}{afterextras}" ++
|
"\\AddBabelHook{" ++ poly ++ "}{afterextras}" ++
|
||||||
"{\\renewcommand{\\text" ++ poly ++ "}[2][]{\\foreignlanguage{"
|
"{\\renewcommand{\\text" ++ poly ++ "}[2][]{\\foreignlanguage{"
|
||||||
++ poly ++ "}{##2}}}\n"
|
++ poly ++ "}{##2}}}"
|
||||||
else (if poly == "latin" -- see #4161
|
else (if poly == "latin" -- see #4161
|
||||||
then "\\providecommand{\\textlatin}{}\n\\renewcommand"
|
then "\\providecommand{\\textlatin}{}\n\\renewcommand"
|
||||||
else "\\newcommand") ++ "{\\text" ++ poly ++
|
else "\\newcommand") ++ "{\\text" ++ poly ++
|
||||||
"}[2][]{\\foreignlanguage{" ++ babel ++ "}{#2}}\n" ++
|
"}[2][]{\\foreignlanguage{" ++ babel ++ "}{#2}}\n" ++
|
||||||
"\\newenvironment{" ++ poly ++
|
"\\newenvironment{" ++ poly ++
|
||||||
"}[2][]{\\begin{otherlanguage}{" ++
|
"}[2][]{\\begin{otherlanguage}{" ++
|
||||||
babel ++ "}}{\\end{otherlanguage}}\n"
|
babel ++ "}}{\\end{otherlanguage}}"
|
||||||
)
|
)
|
||||||
-- eliminate duplicates that have same polyglossia name
|
-- eliminate duplicates that have same polyglossia name
|
||||||
$ nubBy (\a b -> fst a == fst b)
|
$ nubBy (\a b -> fst a == fst b)
|
||||||
|
@ -273,17 +281,19 @@ pandocToLaTeX options (Pandoc meta blocks) = do
|
||||||
$ map (\l -> (fst $ toPolyglossia l, toBabel l)) docLangs
|
$ map (\l -> (fst $ toPolyglossia l, toBabel l)) docLangs
|
||||||
)
|
)
|
||||||
$ maybe id (defField "polyglossia-lang" . toPolyObj) mblang
|
$ maybe id (defField "polyglossia-lang" . toPolyObj) mblang
|
||||||
$ defField "polyglossia-otherlangs" (map toPolyObj docLangs)
|
$ defField "polyglossia-otherlangs"
|
||||||
|
(ListVal (map toPolyObj docLangs :: [Val (Doc Text)]))
|
||||||
$
|
$
|
||||||
defField "latex-dir-rtl"
|
defField "latex-dir-rtl"
|
||||||
(getField "dir" context == Just ("rtl" :: String)) context
|
((render Nothing <$> getField "dir" context) ==
|
||||||
return $
|
Just ("rtl" :: Text)) context
|
||||||
|
return $ render colwidth $
|
||||||
case writerTemplate options of
|
case writerTemplate options of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context'
|
Just tpl -> renderTemplate tpl context'
|
||||||
|
|
||||||
-- | Convert Elements to LaTeX
|
-- | Convert Elements to LaTeX
|
||||||
elementToLaTeX :: PandocMonad m => WriterOptions -> Element -> LW m Doc
|
elementToLaTeX :: PandocMonad m => WriterOptions -> Element -> LW m (Doc Text)
|
||||||
elementToLaTeX _ (Blk block) = blockToLaTeX block
|
elementToLaTeX _ (Blk block) = blockToLaTeX block
|
||||||
elementToLaTeX opts (Sec level _ (id',classes,_) title' elements) = do
|
elementToLaTeX opts (Sec level _ (id',classes,_) title' elements) = do
|
||||||
modify $ \s -> s{stInHeading = True}
|
modify $ \s -> s{stInHeading = True}
|
||||||
|
@ -435,7 +445,7 @@ toLabel z = go `fmap` stringToLaTeX URLString z
|
||||||
| otherwise = "ux" ++ printf "%x" (ord x) ++ go xs
|
| otherwise = "ux" ++ printf "%x" (ord x) ++ go xs
|
||||||
|
|
||||||
-- | Puts contents into LaTeX command.
|
-- | Puts contents into LaTeX command.
|
||||||
inCmd :: String -> Doc -> Doc
|
inCmd :: String -> Doc Text -> Doc Text
|
||||||
inCmd cmd contents = char '\\' <> text cmd <> braces contents
|
inCmd cmd contents = char '\\' <> text cmd <> braces contents
|
||||||
|
|
||||||
toSlides :: PandocMonad m => [Block] -> LW m [Block]
|
toSlides :: PandocMonad m => [Block] -> LW m [Block]
|
||||||
|
@ -514,7 +524,7 @@ isListBlock _ = False
|
||||||
-- | Convert Pandoc block element to LaTeX.
|
-- | Convert Pandoc block element to LaTeX.
|
||||||
blockToLaTeX :: PandocMonad m
|
blockToLaTeX :: PandocMonad m
|
||||||
=> Block -- ^ Block to convert
|
=> Block -- ^ Block to convert
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
blockToLaTeX Null = return empty
|
blockToLaTeX Null = return empty
|
||||||
blockToLaTeX (Div (identifier,classes,kvs) bs)
|
blockToLaTeX (Div (identifier,classes,kvs) bs)
|
||||||
| "incremental" `elem` classes = do
|
| "incremental" `elem` classes = do
|
||||||
|
@ -820,7 +830,8 @@ blockToLaTeX (Table caption aligns widths heads rows) = do
|
||||||
$$ captNotes
|
$$ captNotes
|
||||||
$$ notes
|
$$ notes
|
||||||
|
|
||||||
getCaption :: PandocMonad m => Bool -> [Inline] -> LW m (Doc, Doc, Doc)
|
getCaption :: PandocMonad m
|
||||||
|
=> Bool -> [Inline] -> LW m (Doc Text, Doc Text, Doc Text)
|
||||||
getCaption externalNotes txt = do
|
getCaption externalNotes txt = do
|
||||||
oldExternalNotes <- gets stExternalNotes
|
oldExternalNotes <- gets stExternalNotes
|
||||||
modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }
|
modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }
|
||||||
|
@ -846,7 +857,7 @@ toColDescriptor align =
|
||||||
AlignCenter -> "c"
|
AlignCenter -> "c"
|
||||||
AlignDefault -> "l"
|
AlignDefault -> "l"
|
||||||
|
|
||||||
blockListToLaTeX :: PandocMonad m => [Block] -> LW m Doc
|
blockListToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text)
|
||||||
blockListToLaTeX lst =
|
blockListToLaTeX lst =
|
||||||
vsep `fmap` mapM (\b -> setEmptyLine True >> blockToLaTeX b) lst
|
vsep `fmap` mapM (\b -> setEmptyLine True >> blockToLaTeX b) lst
|
||||||
|
|
||||||
|
@ -855,7 +866,7 @@ tableRowToLaTeX :: PandocMonad m
|
||||||
-> [Alignment]
|
-> [Alignment]
|
||||||
-> [Double]
|
-> [Double]
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
tableRowToLaTeX header aligns widths cols = do
|
tableRowToLaTeX header aligns widths cols = do
|
||||||
-- scale factor compensates for extra space between columns
|
-- scale factor compensates for extra space between columns
|
||||||
-- so the whole table isn't larger than columnwidth
|
-- so the whole table isn't larger than columnwidth
|
||||||
|
@ -897,7 +908,7 @@ displayMathToInline (Math DisplayMath x) = Math InlineMath x
|
||||||
displayMathToInline x = x
|
displayMathToInline x = x
|
||||||
|
|
||||||
tableCellToLaTeX :: PandocMonad m => Bool -> (Double, Alignment, [Block])
|
tableCellToLaTeX :: PandocMonad m => Bool -> (Double, Alignment, [Block])
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
tableCellToLaTeX _ (0, _, blocks) =
|
tableCellToLaTeX _ (0, _, blocks) =
|
||||||
blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
|
blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
|
||||||
tableCellToLaTeX header (width, align, blocks) = do
|
tableCellToLaTeX header (width, align, blocks) = do
|
||||||
|
@ -922,7 +933,7 @@ tableCellToLaTeX header (width, align, blocks) = do
|
||||||
(halign <> cr <> cellContents <> "\\strut" <> cr) <>
|
(halign <> cr <> cellContents <> "\\strut" <> cr) <>
|
||||||
"\\end{minipage}")
|
"\\end{minipage}")
|
||||||
|
|
||||||
notesToLaTeX :: [Doc] -> Doc
|
notesToLaTeX :: [Doc Text] -> Doc Text
|
||||||
notesToLaTeX [] = empty
|
notesToLaTeX [] = empty
|
||||||
notesToLaTeX ns = (case length ns of
|
notesToLaTeX ns = (case length ns of
|
||||||
n | n > 1 -> "\\addtocounter" <>
|
n | n > 1 -> "\\addtocounter" <>
|
||||||
|
@ -935,7 +946,7 @@ notesToLaTeX ns = (case length ns of
|
||||||
$ map (\x -> "\\footnotetext" <> braces x)
|
$ map (\x -> "\\footnotetext" <> braces x)
|
||||||
$ reverse ns)
|
$ reverse ns)
|
||||||
|
|
||||||
listItemToLaTeX :: PandocMonad m => [Block] -> LW m Doc
|
listItemToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text)
|
||||||
listItemToLaTeX lst
|
listItemToLaTeX lst
|
||||||
-- we need to put some text before a header if it's the first
|
-- we need to put some text before a header if it's the first
|
||||||
-- element in an item. This will look ugly in LaTeX regardless, but
|
-- element in an item. This will look ugly in LaTeX regardless, but
|
||||||
|
@ -957,7 +968,7 @@ listItemToLaTeX lst
|
||||||
return $ "\\item" <> brackets checkbox
|
return $ "\\item" <> brackets checkbox
|
||||||
$$ nest 2 (isContents $+$ bsContents)
|
$$ nest 2 (isContents $+$ bsContents)
|
||||||
|
|
||||||
defListItemToLaTeX :: PandocMonad m => ([Inline], [[Block]]) -> LW m Doc
|
defListItemToLaTeX :: PandocMonad m => ([Inline], [[Block]]) -> LW m (Doc Text)
|
||||||
defListItemToLaTeX (term, defs) = do
|
defListItemToLaTeX (term, defs) = do
|
||||||
-- needed to turn off 'listings' because it breaks inside \item[...]:
|
-- needed to turn off 'listings' because it breaks inside \item[...]:
|
||||||
modify $ \s -> s{stInItem = True}
|
modify $ \s -> s{stInItem = True}
|
||||||
|
@ -985,7 +996,7 @@ sectionHeader :: PandocMonad m
|
||||||
-> [Char]
|
-> [Char]
|
||||||
-> Int
|
-> Int
|
||||||
-> [Inline]
|
-> [Inline]
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
sectionHeader unnumbered ident level lst = do
|
sectionHeader unnumbered ident level lst = do
|
||||||
txt <- inlineListToLaTeX lst
|
txt <- inlineListToLaTeX lst
|
||||||
plain <- stringToLaTeX TextString $ concatMap stringify lst
|
plain <- stringToLaTeX TextString $ concatMap stringify lst
|
||||||
|
@ -1002,7 +1013,7 @@ sectionHeader unnumbered ident level lst = do
|
||||||
then return empty
|
then return empty
|
||||||
else
|
else
|
||||||
return $ brackets txtNoNotes
|
return $ brackets txtNoNotes
|
||||||
let contents = if render Nothing txt == plain
|
let contents = if render Nothing txt == T.pack plain
|
||||||
then braces txt
|
then braces txt
|
||||||
else braces (text "\\texorpdfstring"
|
else braces (text "\\texorpdfstring"
|
||||||
<> braces txt
|
<> braces txt
|
||||||
|
@ -1051,7 +1062,7 @@ sectionHeader unnumbered ident level lst = do
|
||||||
braces txtNoNotes
|
braces txtNoNotes
|
||||||
else empty
|
else empty
|
||||||
|
|
||||||
hypertarget :: PandocMonad m => Bool -> String -> Doc -> LW m Doc
|
hypertarget :: PandocMonad m => Bool -> String -> Doc Text -> LW m (Doc Text)
|
||||||
hypertarget _ "" x = return x
|
hypertarget _ "" x = return x
|
||||||
hypertarget addnewline ident x = do
|
hypertarget addnewline ident x = do
|
||||||
ref <- text `fmap` toLabel ident
|
ref <- text `fmap` toLabel ident
|
||||||
|
@ -1061,7 +1072,7 @@ hypertarget addnewline ident x = do
|
||||||
then ("%" <> cr)
|
then ("%" <> cr)
|
||||||
else empty) <> x)
|
else empty) <> x)
|
||||||
|
|
||||||
labelFor :: PandocMonad m => String -> LW m Doc
|
labelFor :: PandocMonad m => String -> LW m (Doc Text)
|
||||||
labelFor "" = return empty
|
labelFor "" = return empty
|
||||||
labelFor ident = do
|
labelFor ident = do
|
||||||
ref <- text `fmap` toLabel ident
|
ref <- text `fmap` toLabel ident
|
||||||
|
@ -1070,7 +1081,7 @@ labelFor ident = do
|
||||||
-- | Convert list of inline elements to LaTeX.
|
-- | Convert list of inline elements to LaTeX.
|
||||||
inlineListToLaTeX :: PandocMonad m
|
inlineListToLaTeX :: PandocMonad m
|
||||||
=> [Inline] -- ^ Inlines to convert
|
=> [Inline] -- ^ Inlines to convert
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
inlineListToLaTeX lst =
|
inlineListToLaTeX lst =
|
||||||
mapM inlineToLaTeX (fixLineInitialSpaces . fixInitialLineBreaks $ lst)
|
mapM inlineToLaTeX (fixLineInitialSpaces . fixInitialLineBreaks $ lst)
|
||||||
>>= return . hcat
|
>>= return . hcat
|
||||||
|
@ -1098,7 +1109,7 @@ isQuoted _ = False
|
||||||
-- | Convert inline element to LaTeX
|
-- | Convert inline element to LaTeX
|
||||||
inlineToLaTeX :: PandocMonad m
|
inlineToLaTeX :: PandocMonad m
|
||||||
=> Inline -- ^ Inline to convert
|
=> Inline -- ^ Inline to convert
|
||||||
-> LW m Doc
|
-> LW m (Doc Text)
|
||||||
inlineToLaTeX (Span (id',classes,kvs) ils) = do
|
inlineToLaTeX (Span (id',classes,kvs) ils) = do
|
||||||
linkAnchor <- hypertarget False id' empty
|
linkAnchor <- hypertarget False id' empty
|
||||||
lang <- toLang $ lookup "lang" kvs
|
lang <- toLang $ lookup "lang" kvs
|
||||||
|
@ -1293,7 +1304,7 @@ inlineToLaTeX (Image attr _ (source, _)) = do
|
||||||
dimList = showDim Width ++ showDim Height
|
dimList = showDim Width ++ showDim Height
|
||||||
dims = if null dimList
|
dims = if null dimList
|
||||||
then empty
|
then empty
|
||||||
else brackets $ cat (intersperse "," dimList)
|
else brackets $ mconcat (intersperse "," dimList)
|
||||||
source' = if isURI source
|
source' = if isURI source
|
||||||
then source
|
then source
|
||||||
else unEscapeString source
|
else unEscapeString source
|
||||||
|
@ -1342,7 +1353,7 @@ protectCode x = [x]
|
||||||
setEmptyLine :: PandocMonad m => Bool -> LW m ()
|
setEmptyLine :: PandocMonad m => Bool -> LW m ()
|
||||||
setEmptyLine b = modify $ \st -> st{ stEmptyLine = b }
|
setEmptyLine b = modify $ \st -> st{ stEmptyLine = b }
|
||||||
|
|
||||||
citationsToNatbib :: PandocMonad m => [Citation] -> LW m Doc
|
citationsToNatbib :: PandocMonad m => [Citation] -> LW m (Doc Text)
|
||||||
citationsToNatbib
|
citationsToNatbib
|
||||||
[one]
|
[one]
|
||||||
= citeCommand c p s k
|
= citeCommand c p s k
|
||||||
|
@ -1393,13 +1404,13 @@ citationsToNatbib cits = do
|
||||||
NormalCitation -> citeCommand "citealp" p s k
|
NormalCitation -> citeCommand "citealp" p s k
|
||||||
|
|
||||||
citeCommand :: PandocMonad m
|
citeCommand :: PandocMonad m
|
||||||
=> String -> [Inline] -> [Inline] -> String -> LW m Doc
|
=> String -> [Inline] -> [Inline] -> String -> LW m (Doc Text)
|
||||||
citeCommand c p s k = do
|
citeCommand c p s k = do
|
||||||
args <- citeArguments p s k
|
args <- citeArguments p s k
|
||||||
return $ text ("\\" ++ c) <> args
|
return $ text ("\\" ++ c) <> args
|
||||||
|
|
||||||
citeArguments :: PandocMonad m
|
citeArguments :: PandocMonad m
|
||||||
=> [Inline] -> [Inline] -> String -> LW m Doc
|
=> [Inline] -> [Inline] -> String -> LW m (Doc Text)
|
||||||
citeArguments p s k = do
|
citeArguments p s k = do
|
||||||
let s' = case s of
|
let s' = case s of
|
||||||
(Str
|
(Str
|
||||||
|
@ -1414,7 +1425,7 @@ citeArguments p s k = do
|
||||||
(_ , _ ) -> brackets pdoc <> brackets sdoc
|
(_ , _ ) -> brackets pdoc <> brackets sdoc
|
||||||
return $ optargs <> braces (text k)
|
return $ optargs <> braces (text k)
|
||||||
|
|
||||||
citationsToBiblatex :: PandocMonad m => [Citation] -> LW m Doc
|
citationsToBiblatex :: PandocMonad m => [Citation] -> LW m (Doc Text)
|
||||||
citationsToBiblatex
|
citationsToBiblatex
|
||||||
[one]
|
[one]
|
||||||
= citeCommand cmd p s k
|
= citeCommand cmd p s k
|
||||||
|
|
|
@ -24,10 +24,10 @@ import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Walk (walk)
|
import Text.Pandoc.Walk (walk)
|
||||||
import Text.Pandoc.Templates
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Pandoc.Writers.Roff
|
import Text.Pandoc.Writers.Roff
|
||||||
|
@ -44,10 +44,8 @@ pandocToMan opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
titleText <- inlineListToMan opts $ docTitle meta
|
titleText <- inlineListToMan opts $ docTitle meta
|
||||||
let title' = render' titleText
|
let title' = render Nothing titleText
|
||||||
let setFieldsFromTitle =
|
let setFieldsFromTitle =
|
||||||
case T.break (== ' ') title' of
|
case T.break (== ' ') title' of
|
||||||
(cmdName, rest) -> case T.break (=='(') cmdName of
|
(cmdName, rest) -> case T.break (=='(') cmdName of
|
||||||
|
@ -62,21 +60,21 @@ pandocToMan opts (Pandoc meta blocks) = do
|
||||||
(T.strip $ mconcat hds)
|
(T.strip $ mconcat hds)
|
||||||
[] -> id
|
[] -> id
|
||||||
_ -> defField "title" title'
|
_ -> defField "title" title'
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap render' . blockListToMan opts)
|
(blockListToMan opts)
|
||||||
(fmap render' . inlineListToMan opts)
|
(fmap chomp . inlineListToMan opts)
|
||||||
$ deleteMeta "title" meta
|
$ deleteMeta "title" meta
|
||||||
body <- blockListToMan opts blocks
|
body <- blockListToMan opts blocks
|
||||||
notes <- gets stNotes
|
notes <- gets stNotes
|
||||||
notes' <- notesToMan opts (reverse notes)
|
notes' <- notesToMan opts (reverse notes)
|
||||||
let main = render' $ body $$ notes' $$ text ""
|
let main = body $$ notes' $$ text ""
|
||||||
hasTables <- gets stHasTables
|
hasTables <- gets stHasTables
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ setFieldsFromTitle
|
$ setFieldsFromTitle
|
||||||
$ defField "has-tables" hasTables
|
$ defField "has-tables" hasTables
|
||||||
$ defField "hyphenate" True
|
$ defField "hyphenate" True
|
||||||
$ defField "pandoc-version" pandocVersion metadata
|
$ defField "pandoc-version" (T.pack pandocVersion) metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -85,7 +83,7 @@ escString :: WriterOptions -> String -> String
|
||||||
escString _ = escapeString AsciiOnly -- for better portability
|
escString _ = escapeString AsciiOnly -- for better portability
|
||||||
|
|
||||||
-- | Return man representation of notes.
|
-- | Return man representation of notes.
|
||||||
notesToMan :: PandocMonad m => WriterOptions -> [[Block]] -> StateT WriterState m Doc
|
notesToMan :: PandocMonad m => WriterOptions -> [[Block]] -> StateT WriterState m (Doc Text)
|
||||||
notesToMan opts notes =
|
notesToMan opts notes =
|
||||||
if null notes
|
if null notes
|
||||||
then return empty
|
then return empty
|
||||||
|
@ -93,7 +91,7 @@ notesToMan opts notes =
|
||||||
return . (text ".SH NOTES" $$) . vcat
|
return . (text ".SH NOTES" $$) . vcat
|
||||||
|
|
||||||
-- | Return man representation of a note.
|
-- | Return man representation of a note.
|
||||||
noteToMan :: PandocMonad m => WriterOptions -> Int -> [Block] -> StateT WriterState m Doc
|
noteToMan :: PandocMonad m => WriterOptions -> Int -> [Block] -> StateT WriterState m (Doc Text)
|
||||||
noteToMan opts num note = do
|
noteToMan opts num note = do
|
||||||
contents <- blockListToMan opts note
|
contents <- blockListToMan opts note
|
||||||
let marker = cr <> text ".SS " <> brackets (text (show num))
|
let marker = cr <> text ".SS " <> brackets (text (show num))
|
||||||
|
@ -107,7 +105,7 @@ noteToMan opts num note = do
|
||||||
blockToMan :: PandocMonad m
|
blockToMan :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
blockToMan _ Null = return empty
|
blockToMan _ Null = return empty
|
||||||
blockToMan opts (Div _ bs) = blockListToMan opts bs
|
blockToMan opts (Div _ bs) = blockListToMan opts bs
|
||||||
blockToMan opts (Plain inlines) =
|
blockToMan opts (Plain inlines) =
|
||||||
|
@ -187,7 +185,7 @@ blockToMan opts (DefinitionList items) = do
|
||||||
return (vcat contents)
|
return (vcat contents)
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to man.
|
-- | Convert bullet list item (list of blocks) to man.
|
||||||
bulletListItemToMan :: PandocMonad m => WriterOptions -> [Block] -> StateT WriterState m Doc
|
bulletListItemToMan :: PandocMonad m => WriterOptions -> [Block] -> StateT WriterState m (Doc Text)
|
||||||
bulletListItemToMan _ [] = return empty
|
bulletListItemToMan _ [] = return empty
|
||||||
bulletListItemToMan opts (Para first:rest) =
|
bulletListItemToMan opts (Para first:rest) =
|
||||||
bulletListItemToMan opts (Plain first:rest)
|
bulletListItemToMan opts (Plain first:rest)
|
||||||
|
@ -210,7 +208,7 @@ orderedListItemToMan :: PandocMonad m
|
||||||
-> String -- ^ order marker for list item
|
-> String -- ^ order marker for list item
|
||||||
-> Int -- ^ number of spaces to indent
|
-> Int -- ^ number of spaces to indent
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
orderedListItemToMan _ _ _ [] = return empty
|
orderedListItemToMan _ _ _ [] = return empty
|
||||||
orderedListItemToMan opts num indent (Para first:rest) =
|
orderedListItemToMan opts num indent (Para first:rest) =
|
||||||
orderedListItemToMan opts num indent (Plain first:rest)
|
orderedListItemToMan opts num indent (Plain first:rest)
|
||||||
|
@ -228,7 +226,7 @@ orderedListItemToMan opts num indent (first:rest) = do
|
||||||
definitionListItemToMan :: PandocMonad m
|
definitionListItemToMan :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Inline],[[Block]])
|
-> ([Inline],[[Block]])
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
definitionListItemToMan opts (label, defs) = do
|
definitionListItemToMan opts (label, defs) = do
|
||||||
-- in most man pages, option and other code in option lists is boldface,
|
-- in most man pages, option and other code in option lists is boldface,
|
||||||
-- but not other things, so we try to reproduce this style:
|
-- but not other things, so we try to reproduce this style:
|
||||||
|
@ -260,16 +258,16 @@ makeCodeBold = walk go
|
||||||
blockListToMan :: PandocMonad m
|
blockListToMan :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> StateT WriterState m Doc
|
-> StateT WriterState m (Doc Text)
|
||||||
blockListToMan opts blocks =
|
blockListToMan opts blocks =
|
||||||
vcat <$> mapM (blockToMan opts) blocks
|
vcat <$> mapM (blockToMan opts) blocks
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to man.
|
-- | Convert list of Pandoc inline elements to man.
|
||||||
inlineListToMan :: PandocMonad m => WriterOptions -> [Inline] -> StateT WriterState m Doc
|
inlineListToMan :: PandocMonad m => WriterOptions -> [Inline] -> StateT WriterState m (Doc Text)
|
||||||
inlineListToMan opts lst = hcat <$> mapM (inlineToMan opts) lst
|
inlineListToMan opts lst = hcat <$> mapM (inlineToMan opts) lst
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to man.
|
-- | Convert Pandoc inline element to man.
|
||||||
inlineToMan :: PandocMonad m => WriterOptions -> Inline -> StateT WriterState m Doc
|
inlineToMan :: PandocMonad m => WriterOptions -> Inline -> StateT WriterState m (Doc Text)
|
||||||
inlineToMan opts (Span _ ils) = inlineListToMan opts ils
|
inlineToMan opts (Span _ ils) = inlineListToMan opts ils
|
||||||
inlineToMan opts (Emph lst) =
|
inlineToMan opts (Emph lst) =
|
||||||
withFontFeature 'I' (inlineListToMan opts lst)
|
withFontFeature 'I' (inlineListToMan opts lst)
|
||||||
|
|
|
@ -20,20 +20,16 @@ module Text.Pandoc.Writers.Markdown (writeMarkdown, writePlain) where
|
||||||
import Prelude
|
import Prelude
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
import Data.Char (isPunctuation, isSpace, isAlphaNum)
|
import Data.Char (isSpace, isAlphaNum)
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import qualified Data.HashMap.Strict as H
|
|
||||||
import Data.List (find, group, intersperse, sortBy, stripPrefix, transpose,
|
import Data.List (find, group, intersperse, sortBy, stripPrefix, transpose,
|
||||||
isPrefixOf)
|
isPrefixOf)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe, catMaybes)
|
||||||
import Data.Ord (comparing)
|
import Data.Ord (comparing)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Scientific as Scientific
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Vector as V
|
|
||||||
import Data.Aeson (Value (Array, Bool, Number, Object, String))
|
|
||||||
import Network.HTTP (urlEncode)
|
import Network.HTTP (urlEncode)
|
||||||
import Text.HTML.TagSoup (Tag (..), isTagText, parseTags)
|
import Text.HTML.TagSoup (Tag (..), isTagText, parseTags)
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
|
@ -41,13 +37,14 @@ import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Parsing hiding (blankline, blanklines, char, space)
|
import Text.Pandoc.Parsing hiding (blankline, blanklines, char, space)
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
|
import Text.DocTemplates (Val(..), Context(..), FromContext(..))
|
||||||
import Text.Pandoc.Walk
|
import Text.Pandoc.Walk
|
||||||
import Text.Pandoc.Writers.HTML (writeHtml5String)
|
import Text.Pandoc.Writers.HTML (writeHtml5String)
|
||||||
import Text.Pandoc.Writers.Math (texMathToInlines)
|
import Text.Pandoc.Writers.Math (texMathToInlines)
|
||||||
import Text.Pandoc.Writers.Shared
|
|
||||||
import Text.Pandoc.XML (toHtml5Entities)
|
import Text.Pandoc.XML (toHtml5Entities)
|
||||||
|
|
||||||
type Notes = [[Block]]
|
type Notes = [[Block]]
|
||||||
|
@ -109,68 +106,82 @@ writePlain :: PandocMonad m => WriterOptions -> Pandoc -> m Text
|
||||||
writePlain opts document =
|
writePlain opts document =
|
||||||
evalMD (pandocToMarkdown opts document) def{ envPlain = True } def
|
evalMD (pandocToMarkdown opts document) def{ envPlain = True } def
|
||||||
|
|
||||||
pandocTitleBlock :: Doc -> [Doc] -> Doc -> Doc
|
pandocTitleBlock :: Doc Text -> [Doc Text] -> Doc Text -> Doc Text
|
||||||
pandocTitleBlock tit auths dat =
|
pandocTitleBlock tit auths dat =
|
||||||
hang 2 (text "% ") tit <> cr <>
|
hang 2 (text "% ") tit <> cr <>
|
||||||
hang 2 (text "% ") (vcat $ map nowrap auths) <> cr <>
|
hang 2 (text "% ") (vcat $ map nowrap auths) <> cr <>
|
||||||
hang 2 (text "% ") dat <> cr
|
hang 2 (text "% ") dat <> cr
|
||||||
|
|
||||||
mmdTitleBlock :: Value -> Doc
|
mmdTitleBlock :: Context (Doc Text) -> Doc Text
|
||||||
mmdTitleBlock (Object hashmap) =
|
mmdTitleBlock (Context hashmap) =
|
||||||
vcat $ map go $ sortBy (comparing fst) $ H.toList hashmap
|
vcat $ map go $ sortBy (comparing fst) $ M.toList hashmap
|
||||||
where go (k,v) =
|
where go (k,v) =
|
||||||
case (text (T.unpack k), v) of
|
case (text (T.unpack k), v) of
|
||||||
(k', Array vec)
|
(k', ListVal xs)
|
||||||
| V.null vec -> empty
|
| null xs -> empty
|
||||||
| otherwise -> k' <> ":" <> space <>
|
| otherwise -> k' <> ":" <> space <>
|
||||||
hcat (intersperse "; "
|
hcat (intersperse "; " $
|
||||||
(map fromstr $ V.toList vec))
|
catMaybes $ map fromVal xs)
|
||||||
(_, String "") -> empty
|
(k', SimpleVal x)
|
||||||
(k', x) -> k' <> ":" <> space <> nest 2 (fromstr x)
|
| isEmpty x -> empty
|
||||||
fromstr (String s) = text (removeBlankLines $ T.unpack s)
|
| otherwise -> k' <> ":" <> space <>
|
||||||
fromstr (Bool b) = text (show b)
|
nest 2 (chomp (removeBlankLines x))
|
||||||
fromstr (Number n) = text (show n)
|
_ -> empty
|
||||||
fromstr _ = empty
|
removeBlankLines BlankLines{} = cr <> text "." <> cr
|
||||||
-- blank lines not allowed in MMD metadata - we replace with .
|
removeBlankLines (Concat x y) = removeBlankLines x <>
|
||||||
removeBlankLines = trimr . unlines . map (\x ->
|
removeBlankLines y
|
||||||
if all isSpace x then "." else x) . lines
|
removeBlankLines x = x
|
||||||
mmdTitleBlock _ = empty
|
|
||||||
|
|
||||||
plainTitleBlock :: Doc -> [Doc] -> Doc -> Doc
|
plainTitleBlock :: Doc Text -> [Doc Text] -> Doc Text -> Doc Text
|
||||||
plainTitleBlock tit auths dat =
|
plainTitleBlock tit auths dat =
|
||||||
tit <> cr <>
|
tit <> cr <>
|
||||||
(hcat (intersperse (text "; ") auths)) <> cr <>
|
(hcat (intersperse (text "; ") auths)) <> cr <>
|
||||||
dat <> cr
|
dat <> cr
|
||||||
|
|
||||||
yamlMetadataBlock :: Value -> Doc
|
yamlMetadataBlock :: Context (Doc Text) -> Doc Text
|
||||||
yamlMetadataBlock v = "---" $$ (jsonToYaml v) $$ "---"
|
yamlMetadataBlock v = "---" $$ (contextToYaml v) $$ "---"
|
||||||
|
|
||||||
jsonToYaml :: Value -> Doc
|
contextToYaml :: Context (Doc Text) -> Doc Text
|
||||||
jsonToYaml (Object hashmap) =
|
contextToYaml (Context o) =
|
||||||
vcat $ map (\(k,v) ->
|
vcat $ map keyvalToYaml $ sortBy (comparing fst) $ M.toList o
|
||||||
case (text (T.unpack k), v, jsonToYaml v) of
|
where
|
||||||
(k', Array vec, x)
|
keyvalToYaml (k,v) =
|
||||||
| V.null vec -> empty
|
case (text (T.unpack k), v) of
|
||||||
| otherwise -> (k' <> ":") $$ x
|
(k', ListVal vs)
|
||||||
(k', Object hm, x)
|
| null vs -> empty
|
||||||
| H.null hm -> k' <> ": {}"
|
| otherwise -> (k' <> ":") $$ valToYaml v
|
||||||
| otherwise -> (k' <> ":") $$ nest 2 x
|
(k', MapVal (Context m))
|
||||||
(_, String "", _) -> empty
|
| M.null m -> k' <> ": {}"
|
||||||
(k', _, x) -> k' <> ":" <> space <> hang 2 "" x)
|
| otherwise -> (k' <> ":") $$ nest 2 (valToYaml v)
|
||||||
$ sortBy (comparing fst) $ H.toList hashmap
|
(_, SimpleVal x)
|
||||||
jsonToYaml (Array vec) =
|
| isEmpty x -> empty
|
||||||
vcat $ map (\v -> hang 2 "- " (jsonToYaml v)) $ V.toList vec
|
(_, NullVal) -> empty
|
||||||
jsonToYaml (String "") = empty
|
(k', _) -> k' <> ":" <+> hang 2 "" (valToYaml v)
|
||||||
jsonToYaml (String s) =
|
|
||||||
case T.unpack s of
|
valToYaml :: Val (Doc Text) -> Doc Text
|
||||||
x | '\n' `elem` x -> hang 2 ("|" <> cr) $ text x
|
valToYaml (ListVal xs) =
|
||||||
| not (any isPunctuation x) -> text x
|
vcat $ map (\v -> hang 2 "- " (valToYaml v)) xs
|
||||||
| otherwise -> text $ "'" ++ substitute "'" "''" x ++ "'"
|
valToYaml (MapVal c) = contextToYaml c
|
||||||
jsonToYaml (Bool b) = text $ show b
|
valToYaml (SimpleVal x)
|
||||||
jsonToYaml (Number n)
|
| isEmpty x = empty
|
||||||
| Scientific.isInteger n = text $ show (floor n :: Integer)
|
| otherwise =
|
||||||
| otherwise = text $ show n
|
if hasNewlines x
|
||||||
jsonToYaml _ = empty
|
then hang 0 ("|" <> cr) x
|
||||||
|
else if any hasPunct x
|
||||||
|
then "'" <> fmap escapeSingleQuotes x <> "'"
|
||||||
|
else x
|
||||||
|
where
|
||||||
|
hasNewlines NewLine = True
|
||||||
|
hasNewlines BlankLines{} = True
|
||||||
|
hasNewlines CarriageReturn = True
|
||||||
|
hasNewlines (Concat w z) = hasNewlines w || hasNewlines z
|
||||||
|
hasNewlines _ = False
|
||||||
|
hasPunct = T.any isYamlPunct
|
||||||
|
isYamlPunct = (`elem` ['-','?',':',',','[',']','{','}',
|
||||||
|
'#','&','*','!','|','>','\'','"',
|
||||||
|
'%','@','`',',','[',']','{','}'])
|
||||||
|
escapeSingleQuotes = T.replace "'" "''"
|
||||||
|
valToYaml _ = empty
|
||||||
|
|
||||||
-- | Return markdown representation of document.
|
-- | Return markdown representation of document.
|
||||||
pandocToMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> MD m Text
|
pandocToMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> MD m Text
|
||||||
|
@ -179,15 +190,13 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
isPlain <- asks envPlain
|
isPlain <- asks envPlain
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext'
|
||||||
render' = render colwidth . chomp
|
(blockListToMarkdown opts)
|
||||||
metadata <- metaToJSON'
|
(inlineListToMarkdown opts)
|
||||||
(fmap render' . blockListToMarkdown opts)
|
|
||||||
(fmap render' . blockToMarkdown opts . Plain)
|
|
||||||
meta
|
meta
|
||||||
let title' = maybe empty text $ getField "title" metadata
|
let title' = maybe empty id $ getField "title" metadata
|
||||||
let authors' = maybe [] (map text) $ getField "author" metadata
|
let authors' = maybe [] id $ getField "author" metadata
|
||||||
let date' = maybe empty text $ getField "date" metadata
|
let date' = maybe empty id $ getField "date" metadata
|
||||||
let titleblock = case writerTemplate opts of
|
let titleblock = case writerTemplate opts of
|
||||||
Just _ | isPlain ->
|
Just _ | isPlain ->
|
||||||
plainTitleBlock title' authors' date'
|
plainTitleBlock title' authors' date'
|
||||||
|
@ -201,9 +210,8 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
|
||||||
Nothing -> empty
|
Nothing -> empty
|
||||||
let headerBlocks = filter isHeaderBlock blocks
|
let headerBlocks = filter isHeaderBlock blocks
|
||||||
toc <- if writerTableOfContents opts
|
toc <- if writerTableOfContents opts
|
||||||
then render' <$> blockToMarkdown opts
|
then blockToMarkdown opts ( toTableOfContents opts headerBlocks )
|
||||||
( toTableOfContents opts headerBlocks )
|
else return mempty
|
||||||
else return ""
|
|
||||||
-- Strip off final 'references' header if markdown citations enabled
|
-- Strip off final 'references' header if markdown citations enabled
|
||||||
let blocks' = if isEnabled Ext_citations opts
|
let blocks' = if isEnabled Ext_citations opts
|
||||||
then case reverse blocks of
|
then case reverse blocks of
|
||||||
|
@ -212,7 +220,7 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
|
||||||
else blocks
|
else blocks
|
||||||
body <- blockListToMarkdown opts blocks'
|
body <- blockListToMarkdown opts blocks'
|
||||||
notesAndRefs' <- notesAndRefs opts
|
notesAndRefs' <- notesAndRefs opts
|
||||||
let main = render' $ body <> notesAndRefs'
|
let main = body <> notesAndRefs'
|
||||||
let context = -- for backwards compatibility we populate toc
|
let context = -- for backwards compatibility we populate toc
|
||||||
-- with the contents of the toc, rather than a
|
-- with the contents of the toc, rather than a
|
||||||
-- boolean:
|
-- boolean:
|
||||||
|
@ -221,22 +229,22 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
|
||||||
$ defField "body" main
|
$ defField "body" main
|
||||||
$ (if isNullMeta meta
|
$ (if isNullMeta meta
|
||||||
then id
|
then id
|
||||||
else defField "titleblock" (render' titleblock))
|
else defField "titleblock" titleblock)
|
||||||
$ addVariablesToJSON opts metadata
|
$ addVariablesToContext opts metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Return markdown representation of reference key table.
|
-- | Return markdown representation of reference key table.
|
||||||
refsToMarkdown :: PandocMonad m => WriterOptions -> Refs -> MD m Doc
|
refsToMarkdown :: PandocMonad m => WriterOptions -> Refs -> MD m (Doc Text)
|
||||||
refsToMarkdown opts refs = mapM (keyToMarkdown opts) refs >>= return . vcat
|
refsToMarkdown opts refs = mapM (keyToMarkdown opts) refs >>= return . vcat
|
||||||
|
|
||||||
-- | Return markdown representation of a reference key.
|
-- | Return markdown representation of a reference key.
|
||||||
keyToMarkdown :: PandocMonad m
|
keyToMarkdown :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> Ref
|
-> Ref
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
keyToMarkdown opts (label', (src, tit), attr) = do
|
keyToMarkdown opts (label', (src, tit), attr) = do
|
||||||
let tit' = if null tit
|
let tit' = if null tit
|
||||||
then empty
|
then empty
|
||||||
|
@ -246,7 +254,7 @@ keyToMarkdown opts (label', (src, tit), attr) = do
|
||||||
<+> linkAttributes opts attr
|
<+> linkAttributes opts attr
|
||||||
|
|
||||||
-- | Return markdown representation of notes.
|
-- | Return markdown representation of notes.
|
||||||
notesToMarkdown :: PandocMonad m => WriterOptions -> [[Block]] -> MD m Doc
|
notesToMarkdown :: PandocMonad m => WriterOptions -> [[Block]] -> MD m (Doc Text)
|
||||||
notesToMarkdown opts notes = do
|
notesToMarkdown opts notes = do
|
||||||
n <- gets stNoteNum
|
n <- gets stNoteNum
|
||||||
notes' <- mapM (\(num, note) -> noteToMarkdown opts num note) (zip [n..] notes)
|
notes' <- mapM (\(num, note) -> noteToMarkdown opts num note) (zip [n..] notes)
|
||||||
|
@ -254,7 +262,7 @@ notesToMarkdown opts notes = do
|
||||||
return $ vsep notes'
|
return $ vsep notes'
|
||||||
|
|
||||||
-- | Return markdown representation of a note.
|
-- | Return markdown representation of a note.
|
||||||
noteToMarkdown :: PandocMonad m => WriterOptions -> Int -> [Block] -> MD m Doc
|
noteToMarkdown :: PandocMonad m => WriterOptions -> Int -> [Block] -> MD m (Doc Text)
|
||||||
noteToMarkdown opts num blocks = do
|
noteToMarkdown opts num blocks = do
|
||||||
contents <- blockListToMarkdown opts blocks
|
contents <- blockListToMarkdown opts blocks
|
||||||
let num' = text $ writerIdentifierPrefix opts ++ show num
|
let num' = text $ writerIdentifierPrefix opts ++ show num
|
||||||
|
@ -310,7 +318,7 @@ escapeString opts =
|
||||||
_ -> '.':go cs
|
_ -> '.':go cs
|
||||||
_ -> c : go cs
|
_ -> c : go cs
|
||||||
|
|
||||||
attrsToMarkdown :: Attr -> Doc
|
attrsToMarkdown :: Attr -> Doc Text
|
||||||
attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
|
attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
|
||||||
where attribId = case attribs of
|
where attribId = case attribs of
|
||||||
([],_,_) -> empty
|
([],_,_) -> empty
|
||||||
|
@ -331,7 +339,7 @@ attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
|
||||||
escAttrChar '\\' = text "\\\\"
|
escAttrChar '\\' = text "\\\\"
|
||||||
escAttrChar c = text [c]
|
escAttrChar c = text [c]
|
||||||
|
|
||||||
linkAttributes :: WriterOptions -> Attr -> Doc
|
linkAttributes :: WriterOptions -> Attr -> Doc Text
|
||||||
linkAttributes opts attr =
|
linkAttributes opts attr =
|
||||||
if isEnabled Ext_link_attributes opts && attr /= nullAttr
|
if isEnabled Ext_link_attributes opts && attr /= nullAttr
|
||||||
then attrsToMarkdown attr
|
then attrsToMarkdown attr
|
||||||
|
@ -353,7 +361,7 @@ beginsWithOrderedListMarker str =
|
||||||
Left _ -> False
|
Left _ -> False
|
||||||
Right _ -> True
|
Right _ -> True
|
||||||
|
|
||||||
notesAndRefs :: PandocMonad m => WriterOptions -> MD m Doc
|
notesAndRefs :: PandocMonad m => WriterOptions -> MD m (Doc Text)
|
||||||
notesAndRefs opts = do
|
notesAndRefs opts = do
|
||||||
notes' <- reverse <$> gets stNotes >>= notesToMarkdown opts
|
notes' <- reverse <$> gets stNotes >>= notesToMarkdown opts
|
||||||
modify $ \s -> s { stNotes = [] }
|
modify $ \s -> s { stNotes = [] }
|
||||||
|
@ -375,7 +383,7 @@ notesAndRefs opts = do
|
||||||
blockToMarkdown :: PandocMonad m
|
blockToMarkdown :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
blockToMarkdown opts blk =
|
blockToMarkdown opts blk =
|
||||||
local (\env -> env {envBlockLevel = envBlockLevel env + 1}) $
|
local (\env -> env {envBlockLevel = envBlockLevel env + 1}) $
|
||||||
do doc <- blockToMarkdown' opts blk
|
do doc <- blockToMarkdown' opts blk
|
||||||
|
@ -387,7 +395,7 @@ blockToMarkdown opts blk =
|
||||||
blockToMarkdown' :: PandocMonad m
|
blockToMarkdown' :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
blockToMarkdown' _ Null = return empty
|
blockToMarkdown' _ Null = return empty
|
||||||
blockToMarkdown' opts (Div attrs ils) = do
|
blockToMarkdown' opts (Div attrs ils) = do
|
||||||
contents <- blockListToMarkdown opts ils
|
contents <- blockListToMarkdown opts ils
|
||||||
|
@ -417,7 +425,7 @@ blockToMarkdown' opts (Plain inlines) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let rendered = render colwidth contents
|
let rendered = T.unpack $ render colwidth contents
|
||||||
let escapeMarker (x:xs) | x `elem` (".()" :: String) = '\\':x:xs
|
let escapeMarker (x:xs) | x `elem` (".()" :: String) = '\\':x:xs
|
||||||
| otherwise = x : escapeMarker xs
|
| otherwise = x : escapeMarker xs
|
||||||
escapeMarker [] = []
|
escapeMarker [] = []
|
||||||
|
@ -624,10 +632,10 @@ blockToMarkdown' opts t@(Table caption aligns widths headers rows) = do
|
||||||
rows
|
rows
|
||||||
(id,) <$> pipeTable (all null headers) aligns' rawHeaders rawRows
|
(id,) <$> pipeTable (all null headers) aligns' rawHeaders rawRows
|
||||||
| otherwise -> return $ (id, text "[TABLE]")
|
| otherwise -> return $ (id, text "[TABLE]")
|
||||||
return $ nst $ tbl $$ caption'' $$ blankline
|
return $ nst (tbl $$ caption'') $$ blankline
|
||||||
blockToMarkdown' opts (BulletList items) = do
|
blockToMarkdown' opts (BulletList items) = do
|
||||||
contents <- inList $ mapM (bulletListItemToMarkdown opts) items
|
contents <- inList $ mapM (bulletListItemToMarkdown opts) items
|
||||||
return $ cat contents <> blankline
|
return $ (if isTightList items then vcat else vsep) contents <> blankline
|
||||||
blockToMarkdown' opts (OrderedList (start,sty,delim) items) = do
|
blockToMarkdown' opts (OrderedList (start,sty,delim) items) = do
|
||||||
let start' = if isEnabled Ext_startnum opts then start else 1
|
let start' = if isEnabled Ext_startnum opts then start else 1
|
||||||
let sty' = if isEnabled Ext_fancy_lists opts then sty else DefaultStyle
|
let sty' = if isEnabled Ext_fancy_lists opts then sty else DefaultStyle
|
||||||
|
@ -640,10 +648,10 @@ blockToMarkdown' opts (OrderedList (start,sty,delim) items) = do
|
||||||
contents <- inList $
|
contents <- inList $
|
||||||
mapM (\(item, num) -> orderedListItemToMarkdown opts item num) $
|
mapM (\(item, num) -> orderedListItemToMarkdown opts item num) $
|
||||||
zip markers' items
|
zip markers' items
|
||||||
return $ cat contents <> blankline
|
return $ (if isTightList items then vcat else vsep) contents <> blankline
|
||||||
blockToMarkdown' opts (DefinitionList items) = do
|
blockToMarkdown' opts (DefinitionList items) = do
|
||||||
contents <- inList $ mapM (definitionListItemToMarkdown opts) items
|
contents <- inList $ mapM (definitionListItemToMarkdown opts) items
|
||||||
return $ cat contents <> blankline
|
return $ mconcat contents <> blankline
|
||||||
|
|
||||||
inList :: Monad m => MD m a -> MD m a
|
inList :: Monad m => MD m a -> MD m a
|
||||||
inList p = local (\env -> env {envInList = True}) p
|
inList p = local (\env -> env {envInList = True}) p
|
||||||
|
@ -657,7 +665,9 @@ addMarkdownAttribute s =
|
||||||
x /= "markdown"]
|
x /= "markdown"]
|
||||||
_ -> s
|
_ -> s
|
||||||
|
|
||||||
pipeTable :: PandocMonad m => Bool -> [Alignment] -> [Doc] -> [[Doc]] -> MD m Doc
|
pipeTable :: PandocMonad m
|
||||||
|
=> Bool -> [Alignment] -> [Doc Text] -> [[Doc Text]]
|
||||||
|
-> MD m (Doc Text)
|
||||||
pipeTable headless aligns rawHeaders rawRows = do
|
pipeTable headless aligns rawHeaders rawRows = do
|
||||||
let sp = text " "
|
let sp = text " "
|
||||||
let blockFor AlignLeft x y = lblock (x + 2) (sp <> y) <> lblock 0 empty
|
let blockFor AlignLeft x y = lblock (x + 2) (sp <> y) <> lblock 0 empty
|
||||||
|
@ -687,7 +697,7 @@ pipeTable headless aligns rawHeaders rawRows = do
|
||||||
|
|
||||||
pandocTable :: PandocMonad m
|
pandocTable :: PandocMonad m
|
||||||
=> WriterOptions -> Bool -> Bool -> [Alignment] -> [Double]
|
=> WriterOptions -> Bool -> Bool -> [Alignment] -> [Double]
|
||||||
-> [Doc] -> [[Doc]] -> MD m Doc
|
-> [Doc Text] -> [[Doc Text]] -> MD m (Doc Text)
|
||||||
pandocTable opts multiline headless aligns widths rawHeaders rawRows = do
|
pandocTable opts multiline headless aligns widths rawHeaders rawRows = do
|
||||||
let isSimple = all (==0) widths
|
let isSimple = all (==0) widths
|
||||||
let alignHeader alignment = case alignment of
|
let alignHeader alignment = case alignment of
|
||||||
|
@ -717,7 +727,7 @@ pandocTable opts multiline headless aligns widths rawHeaders rawRows = do
|
||||||
(zipWith3 alignHeader aligns widthsInChars)
|
(zipWith3 alignHeader aligns widthsInChars)
|
||||||
let rows' = map makeRow rawRows
|
let rows' = map makeRow rawRows
|
||||||
let head' = makeRow rawHeaders
|
let head' = makeRow rawHeaders
|
||||||
let underline = cat $ intersperse (text " ") $
|
let underline = mconcat $ intersperse (text " ") $
|
||||||
map (\width -> text (replicate width '-')) widthsInChars
|
map (\width -> text (replicate width '-')) widthsInChars
|
||||||
let border = if multiline
|
let border = if multiline
|
||||||
then text (replicate (sum widthsInChars +
|
then text (replicate (sum widthsInChars +
|
||||||
|
@ -747,7 +757,7 @@ itemEndsWithTightList bs =
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to markdown.
|
-- | Convert bullet list item (list of blocks) to markdown.
|
||||||
bulletListItemToMarkdown :: PandocMonad m => WriterOptions -> [Block] -> MD m Doc
|
bulletListItemToMarkdown :: PandocMonad m => WriterOptions -> [Block] -> MD m (Doc Text)
|
||||||
bulletListItemToMarkdown opts bs = do
|
bulletListItemToMarkdown opts bs = do
|
||||||
let exts = writerExtensions opts
|
let exts = writerExtensions opts
|
||||||
contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs
|
contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs
|
||||||
|
@ -757,14 +767,14 @@ bulletListItemToMarkdown opts bs = do
|
||||||
let contents' = if itemEndsWithTightList bs
|
let contents' = if itemEndsWithTightList bs
|
||||||
then chomp contents <> cr
|
then chomp contents <> cr
|
||||||
else contents
|
else contents
|
||||||
return $ hang (writerTabStop opts) start $ contents' <> cr
|
return $ hang (writerTabStop opts) start $ contents'
|
||||||
|
|
||||||
-- | Convert ordered list item (a list of blocks) to markdown.
|
-- | Convert ordered list item (a list of blocks) to markdown.
|
||||||
orderedListItemToMarkdown :: PandocMonad m
|
orderedListItemToMarkdown :: PandocMonad m
|
||||||
=> WriterOptions -- ^ options
|
=> WriterOptions -- ^ options
|
||||||
-> String -- ^ list item marker
|
-> String -- ^ list item marker
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
orderedListItemToMarkdown opts marker bs = do
|
orderedListItemToMarkdown opts marker bs = do
|
||||||
let exts = writerExtensions opts
|
let exts = writerExtensions opts
|
||||||
contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs
|
contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs
|
||||||
|
@ -779,13 +789,13 @@ orderedListItemToMarkdown opts marker bs = do
|
||||||
let contents' = if itemEndsWithTightList bs
|
let contents' = if itemEndsWithTightList bs
|
||||||
then chomp contents <> cr
|
then chomp contents <> cr
|
||||||
else contents
|
else contents
|
||||||
return $ hang ind start $ contents' <> cr
|
return $ hang ind start $ contents'
|
||||||
|
|
||||||
-- | Convert definition list item (label, list of blocks) to markdown.
|
-- | Convert definition list item (label, list of blocks) to markdown.
|
||||||
definitionListItemToMarkdown :: PandocMonad m
|
definitionListItemToMarkdown :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Inline],[[Block]])
|
-> ([Inline],[[Block]])
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
definitionListItemToMarkdown opts (label, defs) = do
|
definitionListItemToMarkdown opts (label, defs) = do
|
||||||
labelText <- blockToMarkdown opts (Plain label)
|
labelText <- blockToMarkdown opts (Plain label)
|
||||||
defs' <- mapM (mapM (blockToMarkdown opts)) defs
|
defs' <- mapM (mapM (blockToMarkdown opts)) defs
|
||||||
|
@ -797,17 +807,18 @@ definitionListItemToMarkdown opts (label, defs) = do
|
||||||
let sps = case writerTabStop opts - 3 of
|
let sps = case writerTabStop opts - 3 of
|
||||||
n | n > 0 -> text $ replicate n ' '
|
n | n > 0 -> text $ replicate n ' '
|
||||||
_ -> text " "
|
_ -> text " "
|
||||||
|
let isTight = case defs of
|
||||||
|
((Plain _ : _): _) -> True
|
||||||
|
_ -> False
|
||||||
if isEnabled Ext_compact_definition_lists opts
|
if isEnabled Ext_compact_definition_lists opts
|
||||||
then do
|
then do
|
||||||
let contents = vcat $ map (\d -> hang tabStop (leader <> sps)
|
let contents = vcat $ map (\d -> hang tabStop (leader <> sps)
|
||||||
$ vcat d <> cr) defs'
|
$ vcat d <> cr) defs'
|
||||||
return $ nowrap labelText <> cr <> contents <> cr
|
return $ nowrap labelText <> cr <> contents <> cr
|
||||||
else do
|
else do
|
||||||
let contents = vcat $ map (\d -> hang tabStop (leader <> sps)
|
let contents = (if isTight then vcat else vsep) $ map
|
||||||
$ vcat d <> cr) defs'
|
(\d -> hang tabStop (leader <> sps) $ vcat d)
|
||||||
let isTight = case defs of
|
defs'
|
||||||
((Plain _ : _): _) -> True
|
|
||||||
_ -> False
|
|
||||||
return $ blankline <> nowrap labelText $$
|
return $ blankline <> nowrap labelText $$
|
||||||
(if isTight then empty else blankline) <> contents <> blankline
|
(if isTight then empty else blankline) <> contents <> blankline
|
||||||
else do
|
else do
|
||||||
|
@ -818,7 +829,7 @@ definitionListItemToMarkdown opts (label, defs) = do
|
||||||
blockListToMarkdown :: PandocMonad m
|
blockListToMarkdown :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> MD m Doc
|
-> MD m (Doc Text)
|
||||||
blockListToMarkdown opts blocks = do
|
blockListToMarkdown opts blocks = do
|
||||||
inlist <- asks envInList
|
inlist <- asks envInList
|
||||||
isPlain <- asks envPlain
|
isPlain <- asks envPlain
|
||||||
|
@ -860,10 +871,10 @@ blockListToMarkdown opts blocks = do
|
||||||
else if isEnabled Ext_raw_html opts
|
else if isEnabled Ext_raw_html opts
|
||||||
then RawBlock "html" "<!-- -->\n"
|
then RawBlock "html" "<!-- -->\n"
|
||||||
else RawBlock "markdown" " \n"
|
else RawBlock "markdown" " \n"
|
||||||
mapM (blockToMarkdown opts) (fixBlocks blocks) >>= return . cat
|
mapM (blockToMarkdown opts) (fixBlocks blocks) >>= return . mconcat
|
||||||
|
|
||||||
getKey :: Doc -> Key
|
getKey :: Doc Text -> Key
|
||||||
getKey = toKey . render Nothing
|
getKey = toKey . T.unpack . render Nothing
|
||||||
|
|
||||||
findUsableIndex :: [String] -> Int -> Int
|
findUsableIndex :: [String] -> Int -> Int
|
||||||
findUsableIndex lbls i = if (show i) `elem` lbls
|
findUsableIndex lbls i = if (show i) `elem` lbls
|
||||||
|
@ -880,7 +891,7 @@ getNextIndex = do
|
||||||
|
|
||||||
-- | Get reference for target; if none exists, create unique one and return.
|
-- | Get reference for target; if none exists, create unique one and return.
|
||||||
-- Prefer label if possible; otherwise, generate a unique key.
|
-- Prefer label if possible; otherwise, generate a unique key.
|
||||||
getReference :: PandocMonad m => Attr -> Doc -> Target -> MD m String
|
getReference :: PandocMonad m => Attr -> Doc Text -> Target -> MD m String
|
||||||
getReference attr label target = do
|
getReference attr label target = do
|
||||||
refs <- gets stRefs
|
refs <- gets stRefs
|
||||||
case find (\(_,t,a) -> t == target && a == attr) refs of
|
case find (\(_,t,a) -> t == target && a == attr) refs of
|
||||||
|
@ -894,7 +905,8 @@ getReference attr label target = do
|
||||||
i <- getNextIndex
|
i <- getNextIndex
|
||||||
modify $ \s -> s{ stLastIdx = i }
|
modify $ \s -> s{ stLastIdx = i }
|
||||||
return (show i, i)
|
return (show i, i)
|
||||||
else return (render Nothing label, 0)
|
else
|
||||||
|
return (T.unpack (render Nothing label), 0)
|
||||||
modify (\s -> s{
|
modify (\s -> s{
|
||||||
stRefs = (lab', target, attr) : refs,
|
stRefs = (lab', target, attr) : refs,
|
||||||
stKeys = M.insert (getKey label)
|
stKeys = M.insert (getKey label)
|
||||||
|
@ -905,7 +917,7 @@ getReference attr label target = do
|
||||||
Just km -> do -- we have refs with this label
|
Just km -> do -- we have refs with this label
|
||||||
case M.lookup (target, attr) km of
|
case M.lookup (target, attr) km of
|
||||||
Just i -> do
|
Just i -> do
|
||||||
let lab' = render Nothing $
|
let lab' = T.unpack $ render Nothing $
|
||||||
label <> if i == 0
|
label <> if i == 0
|
||||||
then mempty
|
then mempty
|
||||||
else text (show i)
|
else text (show i)
|
||||||
|
@ -928,7 +940,7 @@ getReference attr label target = do
|
||||||
return lab'
|
return lab'
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to markdown.
|
-- | Convert list of Pandoc inline elements to markdown.
|
||||||
inlineListToMarkdown :: PandocMonad m => WriterOptions -> [Inline] -> MD m Doc
|
inlineListToMarkdown :: PandocMonad m => WriterOptions -> [Inline] -> MD m (Doc Text)
|
||||||
inlineListToMarkdown opts lst = do
|
inlineListToMarkdown opts lst = do
|
||||||
inlist <- asks envInList
|
inlist <- asks envInList
|
||||||
go (if inlist then avoidBadWrapsInList lst else lst)
|
go (if inlist then avoidBadWrapsInList lst else lst)
|
||||||
|
@ -998,7 +1010,7 @@ isRight (Right _) = True
|
||||||
isRight (Left _) = False
|
isRight (Left _) = False
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to markdown.
|
-- | Convert Pandoc inline element to markdown.
|
||||||
inlineToMarkdown :: PandocMonad m => WriterOptions -> Inline -> MD m Doc
|
inlineToMarkdown :: PandocMonad m => WriterOptions -> Inline -> MD m (Doc Text)
|
||||||
inlineToMarkdown opts (Span ("",["emoji"],kvs) [Str s]) = do
|
inlineToMarkdown opts (Span ("",["emoji"],kvs) [Str s]) = do
|
||||||
case lookup "data-emoji" kvs of
|
case lookup "data-emoji" kvs of
|
||||||
Just emojiname | isEnabled Ext_emoji opts ->
|
Just emojiname | isEnabled Ext_emoji opts ->
|
||||||
|
@ -1051,7 +1063,7 @@ inlineToMarkdown opts (Superscript lst) =
|
||||||
else if isEnabled Ext_raw_html opts
|
else if isEnabled Ext_raw_html opts
|
||||||
then "<sup>" <> contents <> "</sup>"
|
then "<sup>" <> contents <> "</sup>"
|
||||||
else
|
else
|
||||||
let rendered = render Nothing contents
|
let rendered = T.unpack $ render Nothing contents
|
||||||
in case mapM toSuperscript rendered of
|
in case mapM toSuperscript rendered of
|
||||||
Just r -> text r
|
Just r -> text r
|
||||||
Nothing -> text $ "^(" ++ rendered ++ ")"
|
Nothing -> text $ "^(" ++ rendered ++ ")"
|
||||||
|
@ -1064,7 +1076,7 @@ inlineToMarkdown opts (Subscript lst) =
|
||||||
else if isEnabled Ext_raw_html opts
|
else if isEnabled Ext_raw_html opts
|
||||||
then "<sub>" <> contents <> "</sub>"
|
then "<sub>" <> contents <> "</sub>"
|
||||||
else
|
else
|
||||||
let rendered = render Nothing contents
|
let rendered = T.unpack $ render Nothing contents
|
||||||
in case mapM toSubscript rendered of
|
in case mapM toSubscript rendered of
|
||||||
Just r -> text r
|
Just r -> text r
|
||||||
Nothing -> text $ "_(" ++ rendered ++ ")"
|
Nothing -> text $ "_(" ++ rendered ++ ")"
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty (render)
|
import Text.DocLayout (render)
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -54,9 +54,9 @@ writeMediaWiki opts document =
|
||||||
pandocToMediaWiki :: PandocMonad m => Pandoc -> MediaWikiWriter m Text
|
pandocToMediaWiki :: PandocMonad m => Pandoc -> MediaWikiWriter m Text
|
||||||
pandocToMediaWiki (Pandoc meta blocks) = do
|
pandocToMediaWiki (Pandoc meta blocks) = do
|
||||||
opts <- asks options
|
opts <- asks options
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap trimr . blockListToMediaWiki)
|
(fmap trimr . blockListToMediaWiki)
|
||||||
inlineListToMediaWiki
|
(fmap trimr . inlineListToMediaWiki)
|
||||||
meta
|
meta
|
||||||
body <- blockListToMediaWiki blocks
|
body <- blockListToMediaWiki blocks
|
||||||
notesExist <- gets stNotes
|
notesExist <- gets stNotes
|
||||||
|
@ -66,9 +66,9 @@ pandocToMediaWiki (Pandoc meta blocks) = do
|
||||||
let main = body ++ notes
|
let main = body ++ notes
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "toc" (writerTableOfContents opts) metadata
|
$ defField "toc" (writerTableOfContents opts) metadata
|
||||||
return $
|
return $ pack $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> pack main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Escape special characters for MediaWiki.
|
-- | Escape special characters for MediaWiki.
|
||||||
|
|
|
@ -37,9 +37,9 @@ import Text.Pandoc.Highlighting
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
import Text.Pandoc.Writers.Roff
|
import Text.Pandoc.Writers.Roff
|
||||||
|
@ -57,14 +57,11 @@ pandocToMs opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext opts
|
||||||
render' = render colwidth
|
(blockListToMs opts)
|
||||||
metadata <- metaToJSON opts
|
(fmap chomp . inlineListToMs' opts)
|
||||||
(fmap render' . blockListToMs opts)
|
|
||||||
(fmap render' . inlineListToMs' opts)
|
|
||||||
meta
|
meta
|
||||||
body <- blockListToMs opts blocks
|
main <- blockListToMs opts blocks
|
||||||
let main = render' body
|
|
||||||
hasInlineMath <- gets stHasInlineMath
|
hasInlineMath <- gets stHasInlineMath
|
||||||
let titleMeta = (escapeStr opts . stringify) $ docTitle meta
|
let titleMeta = (escapeStr opts . stringify) $ docTitle meta
|
||||||
let authorsMeta = map (escapeStr opts . stringify) $ docAuthors meta
|
let authorsMeta = map (escapeStr opts . stringify) $ docAuthors meta
|
||||||
|
@ -72,18 +69,18 @@ pandocToMs opts (Pandoc meta blocks) = do
|
||||||
let highlightingMacros = if hasHighlighting
|
let highlightingMacros = if hasHighlighting
|
||||||
then case writerHighlightStyle opts of
|
then case writerHighlightStyle opts of
|
||||||
Nothing -> mempty
|
Nothing -> mempty
|
||||||
Just sty -> render' $ styleToMs sty
|
Just sty -> styleToMs sty
|
||||||
else mempty
|
else mempty
|
||||||
|
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "has-inline-math" hasInlineMath
|
$ defField "has-inline-math" hasInlineMath
|
||||||
$ defField "hyphenate" True
|
$ defField "hyphenate" True
|
||||||
$ defField "pandoc-version" pandocVersion
|
$ defField "pandoc-version" (T.pack pandocVersion)
|
||||||
$ defField "toc" (writerTableOfContents opts)
|
$ defField "toc" (writerTableOfContents opts)
|
||||||
$ defField "title-meta" titleMeta
|
$ defField "title-meta" (T.pack titleMeta)
|
||||||
$ defField "author-meta" (intercalate "; " authorsMeta)
|
$ defField "author-meta" (T.pack $ intercalate "; " authorsMeta)
|
||||||
$ defField "highlighting-macros" highlightingMacros metadata
|
$ defField "highlighting-macros" highlightingMacros metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -112,7 +109,7 @@ toSmallCaps opts (c:cs)
|
||||||
blockToMs :: PandocMonad m
|
blockToMs :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> Block -- ^ Block element
|
-> Block -- ^ Block element
|
||||||
-> MS m Doc
|
-> MS m (Doc Text)
|
||||||
blockToMs _ Null = return empty
|
blockToMs _ Null = return empty
|
||||||
blockToMs opts (Div (ident,_,_) bs) = do
|
blockToMs opts (Div (ident,_,_) bs) = do
|
||||||
let anchor = if null ident
|
let anchor = if null ident
|
||||||
|
@ -264,7 +261,7 @@ blockToMs opts (DefinitionList items) = do
|
||||||
return (vcat contents)
|
return (vcat contents)
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to ms.
|
-- | Convert bullet list item (list of blocks) to ms.
|
||||||
bulletListItemToMs :: PandocMonad m => WriterOptions -> [Block] -> MS m Doc
|
bulletListItemToMs :: PandocMonad m => WriterOptions -> [Block] -> MS m (Doc Text)
|
||||||
bulletListItemToMs _ [] = return empty
|
bulletListItemToMs _ [] = return empty
|
||||||
bulletListItemToMs opts (Para first:rest) =
|
bulletListItemToMs opts (Para first:rest) =
|
||||||
bulletListItemToMs opts (Plain first:rest)
|
bulletListItemToMs opts (Plain first:rest)
|
||||||
|
@ -287,7 +284,7 @@ orderedListItemToMs :: PandocMonad m
|
||||||
-> String -- ^ order marker for list item
|
-> String -- ^ order marker for list item
|
||||||
-> Int -- ^ number of spaces to indent
|
-> Int -- ^ number of spaces to indent
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> MS m Doc
|
-> MS m (Doc Text)
|
||||||
orderedListItemToMs _ _ _ [] = return empty
|
orderedListItemToMs _ _ _ [] = return empty
|
||||||
orderedListItemToMs opts num indent (Para first:rest) =
|
orderedListItemToMs opts num indent (Para first:rest) =
|
||||||
orderedListItemToMs opts num indent (Plain first:rest)
|
orderedListItemToMs opts num indent (Plain first:rest)
|
||||||
|
@ -306,7 +303,7 @@ orderedListItemToMs opts num indent (first:rest) = do
|
||||||
definitionListItemToMs :: PandocMonad m
|
definitionListItemToMs :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Inline],[[Block]])
|
-> ([Inline],[[Block]])
|
||||||
-> MS m Doc
|
-> MS m (Doc Text)
|
||||||
definitionListItemToMs opts (label, defs) = do
|
definitionListItemToMs opts (label, defs) = do
|
||||||
labelText <- inlineListToMs' opts $ map breakToSpace label
|
labelText <- inlineListToMs' opts $ map breakToSpace label
|
||||||
contents <- if null defs
|
contents <- if null defs
|
||||||
|
@ -327,26 +324,26 @@ definitionListItemToMs opts (label, defs) = do
|
||||||
blockListToMs :: PandocMonad m
|
blockListToMs :: PandocMonad m
|
||||||
=> WriterOptions -- ^ Options
|
=> WriterOptions -- ^ Options
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> MS m Doc
|
-> MS m (Doc Text)
|
||||||
blockListToMs opts blocks =
|
blockListToMs opts blocks =
|
||||||
vcat <$> mapM (blockToMs opts) blocks
|
vcat <$> mapM (blockToMs opts) blocks
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to ms.
|
-- | Convert list of Pandoc inline elements to ms.
|
||||||
inlineListToMs :: PandocMonad m => WriterOptions -> [Inline] -> MS m Doc
|
inlineListToMs :: PandocMonad m => WriterOptions -> [Inline] -> MS m (Doc Text)
|
||||||
-- if list starts with ., insert a zero-width character \& so it
|
-- if list starts with ., insert a zero-width character \& so it
|
||||||
-- won't be interpreted as markup if it falls at the beginning of a line.
|
-- won't be interpreted as markup if it falls at the beginning of a line.
|
||||||
inlineListToMs opts lst = hcat <$> mapM (inlineToMs opts) lst
|
inlineListToMs opts lst = hcat <$> mapM (inlineToMs opts) lst
|
||||||
|
|
||||||
-- This version to be used when there is no further inline content;
|
-- This version to be used when there is no further inline content;
|
||||||
-- forces a note at the end.
|
-- forces a note at the end.
|
||||||
inlineListToMs' :: PandocMonad m => WriterOptions -> [Inline] -> MS m Doc
|
inlineListToMs' :: PandocMonad m => WriterOptions -> [Inline] -> MS m (Doc Text)
|
||||||
inlineListToMs' opts lst = do
|
inlineListToMs' opts lst = do
|
||||||
x <- hcat <$> mapM (inlineToMs opts) lst
|
x <- hcat <$> mapM (inlineToMs opts) lst
|
||||||
y <- handleNotes opts empty
|
y <- handleNotes opts empty
|
||||||
return $ x <> y
|
return $ x <> y
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to ms.
|
-- | Convert Pandoc inline element to ms.
|
||||||
inlineToMs :: PandocMonad m => WriterOptions -> Inline -> MS m Doc
|
inlineToMs :: PandocMonad m => WriterOptions -> Inline -> MS m (Doc Text)
|
||||||
inlineToMs opts (Span _ ils) = inlineListToMs opts ils
|
inlineToMs opts (Span _ ils) = inlineListToMs opts ils
|
||||||
inlineToMs opts (Emph lst) =
|
inlineToMs opts (Emph lst) =
|
||||||
withFontFeature 'I' (inlineListToMs opts lst)
|
withFontFeature 'I' (inlineListToMs opts lst)
|
||||||
|
@ -382,7 +379,7 @@ inlineToMs opts (Code attr str) = do
|
||||||
withFontFeature 'C' (return hlCode)
|
withFontFeature 'C' (return hlCode)
|
||||||
inlineToMs opts (Str str) = do
|
inlineToMs opts (Str str) = do
|
||||||
let shim = case str of
|
let shim = case str of
|
||||||
'.':_ -> afterBreak "\\&"
|
'.':_ -> afterBreak (T.pack "\\&")
|
||||||
_ -> empty
|
_ -> empty
|
||||||
smallcaps <- gets stSmallCaps
|
smallcaps <- gets stSmallCaps
|
||||||
if smallcaps
|
if smallcaps
|
||||||
|
@ -437,7 +434,7 @@ inlineToMs _ (Note contents) = do
|
||||||
modify $ \st -> st{ stNotes = contents : stNotes st }
|
modify $ \st -> st{ stNotes = contents : stNotes st }
|
||||||
return $ text "\\**"
|
return $ text "\\**"
|
||||||
|
|
||||||
handleNotes :: PandocMonad m => WriterOptions -> Doc -> MS m Doc
|
handleNotes :: PandocMonad m => WriterOptions -> Doc Text -> MS m (Doc Text)
|
||||||
handleNotes opts fallback = do
|
handleNotes opts fallback = do
|
||||||
notes <- gets stNotes
|
notes <- gets stNotes
|
||||||
if null notes
|
if null notes
|
||||||
|
@ -446,7 +443,7 @@ handleNotes opts fallback = do
|
||||||
modify $ \st -> st{ stNotes = [] }
|
modify $ \st -> st{ stNotes = [] }
|
||||||
vcat <$> mapM (handleNote opts) notes
|
vcat <$> mapM (handleNote opts) notes
|
||||||
|
|
||||||
handleNote :: PandocMonad m => WriterOptions -> Note -> MS m Doc
|
handleNote :: PandocMonad m => WriterOptions -> Note -> MS m (Doc Text)
|
||||||
handleNote opts bs = do
|
handleNote opts bs = do
|
||||||
-- don't start with Paragraph or we'll get a spurious blank
|
-- don't start with Paragraph or we'll get a spurious blank
|
||||||
-- line after the note ref:
|
-- line after the note ref:
|
||||||
|
@ -469,7 +466,7 @@ breakToSpace x = x
|
||||||
|
|
||||||
-- Highlighting
|
-- Highlighting
|
||||||
|
|
||||||
styleToMs :: Style -> Doc
|
styleToMs :: Style -> Doc Text
|
||||||
styleToMs sty = vcat $ colordefs ++ map (toMacro sty) alltoktypes
|
styleToMs sty = vcat $ colordefs ++ map (toMacro sty) alltoktypes
|
||||||
where alltoktypes = enumFromTo KeywordTok NormalTok
|
where alltoktypes = enumFromTo KeywordTok NormalTok
|
||||||
colordefs = map toColorDef allcolors
|
colordefs = map toColorDef allcolors
|
||||||
|
@ -484,7 +481,7 @@ styleToMs sty = vcat $ colordefs ++ map (toMacro sty) alltoktypes
|
||||||
hexColor :: Color -> String
|
hexColor :: Color -> String
|
||||||
hexColor (RGB r g b) = printf "%02x%02x%02x" r g b
|
hexColor (RGB r g b) = printf "%02x%02x%02x" r g b
|
||||||
|
|
||||||
toMacro :: Style -> TokenType -> Doc
|
toMacro :: Style -> TokenType -> Doc Text
|
||||||
toMacro sty toktype =
|
toMacro sty toktype =
|
||||||
nowrap (text ".ds " <> text (show toktype) <> text " " <>
|
nowrap (text ".ds " <> text (show toktype) <> text " " <>
|
||||||
setbg <> setcolor <> setfont <>
|
setbg <> setcolor <> setfont <>
|
||||||
|
@ -512,7 +509,7 @@ toMacro sty toktype =
|
||||||
-- lnColor = lineNumberColor sty
|
-- lnColor = lineNumberColor sty
|
||||||
-- lnBkgColor = lineNumberBackgroundColor sty
|
-- lnBkgColor = lineNumberBackgroundColor sty
|
||||||
|
|
||||||
msFormatter :: WriterOptions -> FormatOptions -> [SourceLine] -> Doc
|
msFormatter :: WriterOptions -> FormatOptions -> [SourceLine] -> Doc Text
|
||||||
msFormatter opts _fmtopts =
|
msFormatter opts _fmtopts =
|
||||||
vcat . map fmtLine
|
vcat . map fmtLine
|
||||||
where fmtLine = hcat . map fmtToken
|
where fmtLine = hcat . map fmtToken
|
||||||
|
@ -520,7 +517,7 @@ msFormatter opts _fmtopts =
|
||||||
brackets (text (show toktype) <> text " \""
|
brackets (text (show toktype) <> text " \""
|
||||||
<> text (escapeStr opts (T.unpack tok)) <> text "\"")
|
<> text (escapeStr opts (T.unpack tok)) <> text "\"")
|
||||||
|
|
||||||
highlightCode :: PandocMonad m => WriterOptions -> Attr -> String -> MS m Doc
|
highlightCode :: PandocMonad m => WriterOptions -> Attr -> String -> MS m (Doc Text)
|
||||||
highlightCode opts attr str =
|
highlightCode opts attr str =
|
||||||
case highlight (writerSyntaxMap opts) (msFormatter opts) attr str of
|
case highlight (writerSyntaxMap opts) (msFormatter opts) attr str of
|
||||||
Left msg -> do
|
Left msg -> do
|
||||||
|
|
|
@ -32,13 +32,14 @@ import Data.Char (isAlphaNum, isAsciiLower, isAsciiUpper, isDigit, isSpace)
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import Data.List (intersperse, isInfixOf, transpose)
|
import Data.List (intersperse, isInfixOf, transpose)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Text as T
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import System.FilePath (takeExtension)
|
import System.FilePath (takeExtension)
|
||||||
import Text.Pandoc.Class (PandocMonad)
|
import Text.Pandoc.Class (PandocMonad)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Math
|
import Text.Pandoc.Writers.Math
|
||||||
|
@ -104,17 +105,15 @@ pandocToMuse (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext opts
|
||||||
render' = render Nothing
|
blockListToMuse
|
||||||
metadata <- metaToJSON opts
|
(fmap chomp . inlineListToMuse)
|
||||||
(fmap render' . blockListToMuse)
|
|
||||||
(fmap render' . inlineListToMuse)
|
|
||||||
meta
|
meta
|
||||||
body <- blockListToMuse blocks
|
body <- blockListToMuse blocks
|
||||||
notes <- currentNotesToMuse
|
notes <- currentNotesToMuse
|
||||||
let main = render colwidth $ body $+$ notes
|
let main = body $+$ notes
|
||||||
let context = defField "body" main metadata
|
let context = defField "body" main metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -124,7 +123,7 @@ pandocToMuse (Pandoc meta blocks) = do
|
||||||
catWithBlankLines :: PandocMonad m
|
catWithBlankLines :: PandocMonad m
|
||||||
=> [Block] -- ^ List of block elements
|
=> [Block] -- ^ List of block elements
|
||||||
-> Int -- ^ Number of blank lines
|
-> Int -- ^ Number of blank lines
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
catWithBlankLines (b : bs) n = do
|
catWithBlankLines (b : bs) n = do
|
||||||
b' <- blockToMuseWithNotes b
|
b' <- blockToMuseWithNotes b
|
||||||
bs' <- flatBlockListToMuse bs
|
bs' <- flatBlockListToMuse bs
|
||||||
|
@ -135,7 +134,7 @@ catWithBlankLines _ _ = error "Expected at least one block"
|
||||||
-- | without setting envTopLevel.
|
-- | without setting envTopLevel.
|
||||||
flatBlockListToMuse :: PandocMonad m
|
flatBlockListToMuse :: PandocMonad m
|
||||||
=> [Block] -- ^ List of block elements
|
=> [Block] -- ^ List of block elements
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
flatBlockListToMuse bs@(BulletList _ : BulletList _ : _) = catWithBlankLines bs 2
|
flatBlockListToMuse bs@(BulletList _ : BulletList _ : _) = catWithBlankLines bs 2
|
||||||
flatBlockListToMuse bs@(OrderedList (_, style1, _) _ : OrderedList (_, style2, _) _ : _) =
|
flatBlockListToMuse bs@(OrderedList (_, style1, _) _ : OrderedList (_, style2, _) _ : _) =
|
||||||
catWithBlankLines bs (if style1' == style2' then 2 else 0)
|
catWithBlankLines bs (if style1' == style2' then 2 else 0)
|
||||||
|
@ -152,7 +151,7 @@ simpleTable :: PandocMonad m
|
||||||
=> [Inline]
|
=> [Inline]
|
||||||
-> [TableCell]
|
-> [TableCell]
|
||||||
-> [[TableCell]]
|
-> [[TableCell]]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
simpleTable caption headers rows = do
|
simpleTable caption headers rows = do
|
||||||
topLevel <- asks envTopLevel
|
topLevel <- asks envTopLevel
|
||||||
caption' <- inlineListToMuse caption
|
caption' <- inlineListToMuse caption
|
||||||
|
@ -175,7 +174,7 @@ simpleTable caption headers rows = do
|
||||||
-- | Convert list of Pandoc block elements to Muse.
|
-- | Convert list of Pandoc block elements to Muse.
|
||||||
blockListToMuse :: PandocMonad m
|
blockListToMuse :: PandocMonad m
|
||||||
=> [Block] -- ^ List of block elements
|
=> [Block] -- ^ List of block elements
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
blockListToMuse =
|
blockListToMuse =
|
||||||
local (\env -> env { envTopLevel = not (envInsideBlock env)
|
local (\env -> env { envTopLevel = not (envInsideBlock env)
|
||||||
, envInsideBlock = True
|
, envInsideBlock = True
|
||||||
|
@ -184,7 +183,7 @@ blockListToMuse =
|
||||||
-- | Convert Pandoc block element to Muse.
|
-- | Convert Pandoc block element to Muse.
|
||||||
blockToMuse :: PandocMonad m
|
blockToMuse :: PandocMonad m
|
||||||
=> Block -- ^ Block element
|
=> Block -- ^ Block element
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
blockToMuse (Plain inlines) = inlineListToMuse' inlines
|
blockToMuse (Plain inlines) = inlineListToMuse' inlines
|
||||||
blockToMuse (Para inlines) = do
|
blockToMuse (Para inlines) = do
|
||||||
contents <- inlineListToMuse' inlines
|
contents <- inlineListToMuse' inlines
|
||||||
|
@ -213,7 +212,7 @@ blockToMuse (OrderedList (start, style, _) items) = do
|
||||||
where orderedListItemToMuse :: PandocMonad m
|
where orderedListItemToMuse :: PandocMonad m
|
||||||
=> String -- ^ marker for list item
|
=> String -- ^ marker for list item
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
orderedListItemToMuse marker item = hang (length marker + 1) (text marker <> space)
|
orderedListItemToMuse marker item = hang (length marker + 1) (text marker <> space)
|
||||||
<$> blockListToMuse item
|
<$> blockListToMuse item
|
||||||
blockToMuse (BulletList items) = do
|
blockToMuse (BulletList items) = do
|
||||||
|
@ -222,7 +221,7 @@ blockToMuse (BulletList items) = do
|
||||||
return $ (if topLevel then nest 1 else id) (vcat contents) $$ blankline
|
return $ (if topLevel then nest 1 else id) (vcat contents) $$ blankline
|
||||||
where bulletListItemToMuse :: PandocMonad m
|
where bulletListItemToMuse :: PandocMonad m
|
||||||
=> [Block]
|
=> [Block]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
bulletListItemToMuse item = do
|
bulletListItemToMuse item = do
|
||||||
modify $ \st -> st { stUseTags = False }
|
modify $ \st -> st { stUseTags = False }
|
||||||
hang 2 "- " <$> blockListToMuse item
|
hang 2 "- " <$> blockListToMuse item
|
||||||
|
@ -232,16 +231,17 @@ blockToMuse (DefinitionList items) = do
|
||||||
return $ (if topLevel then nest 1 else id) (vcat contents) $$ blankline
|
return $ (if topLevel then nest 1 else id) (vcat contents) $$ blankline
|
||||||
where definitionListItemToMuse :: PandocMonad m
|
where definitionListItemToMuse :: PandocMonad m
|
||||||
=> ([Inline], [[Block]])
|
=> ([Inline], [[Block]])
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
definitionListItemToMuse (label, defs) = do
|
definitionListItemToMuse (label, defs) = do
|
||||||
modify $ \st -> st { stUseTags = False }
|
modify $ \st -> st { stUseTags = False }
|
||||||
label' <- local (\env -> env { envOneLine = True, envAfterSpace = True }) $ inlineListToMuse' label
|
label' <- local (\env -> env { envOneLine = True, envAfterSpace = True }) $ inlineListToMuse' label
|
||||||
let ind = offset' label' -- using Text.Pandoc.Pretty.offset results in round trip failures
|
let ind = offset' label' -- using Text.DocLayout.offset results in round trip failures
|
||||||
hang ind (nowrap label') . vcat <$> mapM descriptionToMuse defs
|
hang ind (nowrap label') . vcat <$> mapM descriptionToMuse defs
|
||||||
where offset' d = maximum (0: map length (lines $ render Nothing d))
|
where offset' d = maximum (0: map T.length
|
||||||
|
(T.lines $ render Nothing d))
|
||||||
descriptionToMuse :: PandocMonad m
|
descriptionToMuse :: PandocMonad m
|
||||||
=> [Block]
|
=> [Block]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
descriptionToMuse desc = hang 4 " :: " <$> blockListToMuse desc
|
descriptionToMuse desc = hang 4 " :: " <$> blockListToMuse desc
|
||||||
blockToMuse (Header level (ident,_,_) inlines) = do
|
blockToMuse (Header level (ident,_,_) inlines) = do
|
||||||
opts <- asks envOptions
|
opts <- asks envOptions
|
||||||
|
@ -274,7 +274,7 @@ blockToMuse Null = return empty
|
||||||
|
|
||||||
-- | Return Muse representation of notes collected so far.
|
-- | Return Muse representation of notes collected so far.
|
||||||
currentNotesToMuse :: PandocMonad m
|
currentNotesToMuse :: PandocMonad m
|
||||||
=> Muse m Doc
|
=> Muse m (Doc Text)
|
||||||
currentNotesToMuse = do
|
currentNotesToMuse = do
|
||||||
notes <- reverse <$> gets stNotes
|
notes <- reverse <$> gets stNotes
|
||||||
modify $ \st -> st { stNotes = mempty }
|
modify $ \st -> st { stNotes = mempty }
|
||||||
|
@ -283,7 +283,7 @@ currentNotesToMuse = do
|
||||||
-- | Return Muse representation of notes.
|
-- | Return Muse representation of notes.
|
||||||
notesToMuse :: PandocMonad m
|
notesToMuse :: PandocMonad m
|
||||||
=> Notes
|
=> Notes
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
notesToMuse notes = do
|
notesToMuse notes = do
|
||||||
n <- gets stNoteNum
|
n <- gets stNoteNum
|
||||||
modify $ \st -> st { stNoteNum = stNoteNum st + length notes }
|
modify $ \st -> st { stNoteNum = stNoteNum st + length notes }
|
||||||
|
@ -293,7 +293,7 @@ notesToMuse notes = do
|
||||||
noteToMuse :: PandocMonad m
|
noteToMuse :: PandocMonad m
|
||||||
=> Int
|
=> Int
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
noteToMuse num note = do
|
noteToMuse num note = do
|
||||||
res <- hang (length marker) (text marker) <$>
|
res <- hang (length marker) (text marker) <$>
|
||||||
local (\env -> env { envInsideBlock = True
|
local (\env -> env { envInsideBlock = True
|
||||||
|
@ -307,7 +307,7 @@ noteToMuse num note = do
|
||||||
-- | Return Muse representation of block and accumulated notes.
|
-- | Return Muse representation of block and accumulated notes.
|
||||||
blockToMuseWithNotes :: PandocMonad m
|
blockToMuseWithNotes :: PandocMonad m
|
||||||
=> Block
|
=> Block
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
blockToMuseWithNotes blk = do
|
blockToMuseWithNotes blk = do
|
||||||
topLevel <- asks envTopLevel
|
topLevel <- asks envTopLevel
|
||||||
opts <- asks envOptions
|
opts <- asks envOptions
|
||||||
|
@ -501,7 +501,7 @@ inlineListStartsWithAlnum _ = return False
|
||||||
-- | Convert list of Pandoc inline elements to Muse
|
-- | Convert list of Pandoc inline elements to Muse
|
||||||
renderInlineList :: PandocMonad m
|
renderInlineList :: PandocMonad m
|
||||||
=> [Inline]
|
=> [Inline]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
renderInlineList [] = pure ""
|
renderInlineList [] = pure ""
|
||||||
renderInlineList (x:xs) = do
|
renderInlineList (x:xs) = do
|
||||||
start <- asks envInlineStart
|
start <- asks envInlineStart
|
||||||
|
@ -531,7 +531,7 @@ renderInlineList (x:xs) = do
|
||||||
-- | Normalize and convert list of Pandoc inline elements to Muse.
|
-- | Normalize and convert list of Pandoc inline elements to Muse.
|
||||||
inlineListToMuse :: PandocMonad m
|
inlineListToMuse :: PandocMonad m
|
||||||
=> [Inline]
|
=> [Inline]
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
inlineListToMuse lst = do
|
inlineListToMuse lst = do
|
||||||
lst' <- normalizeInlineList . fixNotes <$> preprocessInlineList (map (removeKeyValues . replaceSmallCaps) lst)
|
lst' <- normalizeInlineList . fixNotes <$> preprocessInlineList (map (removeKeyValues . replaceSmallCaps) lst)
|
||||||
insideAsterisks <- asks envInsideAsterisks
|
insideAsterisks <- asks envInsideAsterisks
|
||||||
|
@ -541,7 +541,7 @@ inlineListToMuse lst = do
|
||||||
then pure "<verbatim></verbatim>"
|
then pure "<verbatim></verbatim>"
|
||||||
else local (\env -> env { envNearAsterisks = insideAsterisks }) $ renderInlineList lst'
|
else local (\env -> env { envNearAsterisks = insideAsterisks }) $ renderInlineList lst'
|
||||||
|
|
||||||
inlineListToMuse' :: PandocMonad m => [Inline] -> Muse m Doc
|
inlineListToMuse' :: PandocMonad m => [Inline] -> Muse m (Doc Text)
|
||||||
inlineListToMuse' lst = do
|
inlineListToMuse' lst = do
|
||||||
topLevel <- asks envTopLevel
|
topLevel <- asks envTopLevel
|
||||||
afterSpace <- asks envAfterSpace
|
afterSpace <- asks envAfterSpace
|
||||||
|
@ -549,7 +549,7 @@ inlineListToMuse' lst = do
|
||||||
, envAfterSpace = afterSpace || not topLevel
|
, envAfterSpace = afterSpace || not topLevel
|
||||||
}) $ inlineListToMuse lst
|
}) $ inlineListToMuse lst
|
||||||
|
|
||||||
emphasis :: PandocMonad m => String -> String -> [Inline] -> Muse m Doc
|
emphasis :: PandocMonad m => String -> String -> [Inline] -> Muse m (Doc Text)
|
||||||
emphasis b e lst = do
|
emphasis b e lst = do
|
||||||
contents <- local (\env -> env { envInsideAsterisks = inAsterisks }) $ inlineListToMuse lst
|
contents <- local (\env -> env { envInsideAsterisks = inAsterisks }) $ inlineListToMuse lst
|
||||||
modify $ \st -> st { stUseTags = useTags }
|
modify $ \st -> st { stUseTags = useTags }
|
||||||
|
@ -560,7 +560,7 @@ emphasis b e lst = do
|
||||||
-- | Convert Pandoc inline element to Muse.
|
-- | Convert Pandoc inline element to Muse.
|
||||||
inlineToMuse :: PandocMonad m
|
inlineToMuse :: PandocMonad m
|
||||||
=> Inline
|
=> Inline
|
||||||
-> Muse m Doc
|
-> Muse m (Doc Text)
|
||||||
inlineToMuse (Str str) = do
|
inlineToMuse (Str str) = do
|
||||||
escapedStr <- conditionalEscapeString $ replaceNewlines str
|
escapedStr <- conditionalEscapeString $ replaceNewlines str
|
||||||
let useTags = isAlphaNum $ last escapedStr -- escapedStr is never empty because empty strings are escaped
|
let useTags = isAlphaNum $ last escapedStr -- escapedStr is never empty because empty strings are escaped
|
||||||
|
|
|
@ -19,15 +19,15 @@ import Data.Text (Text)
|
||||||
import Text.Pandoc.Class (PandocMonad)
|
import Text.Pandoc.Class (PandocMonad)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
|
import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
|
|
||||||
prettyList :: [Doc] -> Doc
|
prettyList :: [Doc Text] -> Doc Text
|
||||||
prettyList ds =
|
prettyList ds =
|
||||||
"[" <>
|
"[" <>
|
||||||
cat (intersperse (cr <> ",") $ map (nest 1) ds) <> "]"
|
mconcat (intersperse (cr <> ",") $ map (nest 1) ds) <> "]"
|
||||||
|
|
||||||
-- | Prettyprint Pandoc block element.
|
-- | Prettyprint Pandoc block element.
|
||||||
prettyBlock :: Block -> Doc
|
prettyBlock :: Block -> Doc Text
|
||||||
prettyBlock (LineBlock lines') =
|
prettyBlock (LineBlock lines') =
|
||||||
"LineBlock" $$ prettyList (map (text . show) lines')
|
"LineBlock" $$ prettyList (map (text . show) lines')
|
||||||
prettyBlock (BlockQuote blocks) =
|
prettyBlock (BlockQuote blocks) =
|
||||||
|
|
|
@ -32,7 +32,7 @@ import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.MIME (extensionFromMimeType, getMimeType)
|
import Text.Pandoc.MIME (extensionFromMimeType, getMimeType)
|
||||||
import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
|
import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared (stringify, pandocVersion)
|
import Text.Pandoc.Shared (stringify, pandocVersion)
|
||||||
import Text.Pandoc.Writers.Shared (lookupMetaString, lookupMetaBlocks,
|
import Text.Pandoc.Writers.Shared (lookupMetaString, lookupMetaBlocks,
|
||||||
fixDisplayMath)
|
fixDisplayMath)
|
||||||
|
|
|
@ -14,7 +14,7 @@ Conversion of 'Pandoc' documents to OPML XML.
|
||||||
module Text.Pandoc.Writers.OPML ( writeOPML) where
|
module Text.Pandoc.Writers.OPML ( writeOPML) where
|
||||||
import Prelude
|
import Prelude
|
||||||
import Control.Monad.Except (throwError)
|
import Control.Monad.Except (throwError)
|
||||||
import Data.Text (Text, unpack)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Text.Pandoc.Builder as B
|
import qualified Text.Pandoc.Builder as B
|
||||||
import Text.Pandoc.Class (PandocMonad)
|
import Text.Pandoc.Class (PandocMonad)
|
||||||
|
@ -22,7 +22,7 @@ import Data.Time
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Error
|
import Text.Pandoc.Error
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.HTML (writeHtml5String)
|
import Text.Pandoc.Writers.HTML (writeHtml5String)
|
||||||
|
@ -38,7 +38,7 @@ writeOPML opts (Pandoc meta blocks) = do
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
meta' = B.setMeta "date" (B.str $ convertDate $ docDate meta) meta
|
meta' = B.setMeta "date" (B.str $ convertDate $ docDate meta) meta
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(writeMarkdown def . Pandoc nullMeta)
|
(writeMarkdown def . Pandoc nullMeta)
|
||||||
(\ils -> T.stripEnd <$> writeMarkdown def (Pandoc nullMeta [Plain ils]))
|
(\ils -> T.stripEnd <$> writeMarkdown def (Pandoc nullMeta [Plain ils]))
|
||||||
meta'
|
meta'
|
||||||
|
@ -64,7 +64,7 @@ convertDate ils = maybe "" showDateTimeRFC822 $
|
||||||
parseTimeM True defaultTimeLocale "%F" =<< normalizeDate (stringify ils)
|
parseTimeM True defaultTimeLocale "%F" =<< normalizeDate (stringify ils)
|
||||||
|
|
||||||
-- | Convert an Element to OPML.
|
-- | Convert an Element to OPML.
|
||||||
elementToOPML :: PandocMonad m => WriterOptions -> Element -> m Doc
|
elementToOPML :: PandocMonad m => WriterOptions -> Element -> m (Doc Text)
|
||||||
elementToOPML _ (Blk _) = return empty
|
elementToOPML _ (Blk _) = return empty
|
||||||
elementToOPML opts (Sec _ _num _ title elements) = do
|
elementToOPML opts (Sec _ _num _ title elements) = do
|
||||||
let isBlk :: Element -> Bool
|
let isBlk :: Element -> Bool
|
||||||
|
@ -81,7 +81,7 @@ elementToOPML opts (Sec _ _num _ title elements) = do
|
||||||
then return mempty
|
then return mempty
|
||||||
else do blks <- mapM fromBlk blocks
|
else do blks <- mapM fromBlk blocks
|
||||||
writeMarkdown def $ Pandoc nullMeta blks
|
writeMarkdown def $ Pandoc nullMeta blks
|
||||||
let attrs = ("text", unpack htmlIls) :
|
let attrs = ("text", T.unpack htmlIls) :
|
||||||
[("_note", unpack md) | not (null blocks)]
|
[("_note", T.unpack $ T.stripEnd md) | not (null blocks)]
|
||||||
o <- mapM (elementToOPML opts) rest
|
o <- mapM (elementToOPML opts) rest
|
||||||
return $ inTags True "outline" attrs $ vcat o
|
return $ inTags True "outline" attrs $ vcat o
|
||||||
|
|
|
@ -30,7 +30,7 @@ import Text.Pandoc.Class (PandocMonad, report, translateTerm,
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared (linesToPara)
|
import Text.Pandoc.Shared (linesToPara)
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import qualified Text.Pandoc.Translations as Term (Term(Figure, Table))
|
import qualified Text.Pandoc.Translations as Term (Term(Figure, Table))
|
||||||
|
@ -51,11 +51,12 @@ plainToPara x = x
|
||||||
type OD m = StateT WriterState m
|
type OD m = StateT WriterState m
|
||||||
|
|
||||||
data WriterState =
|
data WriterState =
|
||||||
WriterState { stNotes :: [Doc]
|
WriterState { stNotes :: [Doc Text]
|
||||||
, stTableStyles :: [Doc]
|
, stTableStyles :: [Doc Text]
|
||||||
, stParaStyles :: [Doc]
|
, stParaStyles :: [Doc Text]
|
||||||
, stListStyles :: [(Int, [Doc])]
|
, stListStyles :: [(Int, [Doc Text])]
|
||||||
, stTextStyles :: Map.Map (Set.Set TextStyle) (String, Doc)
|
, stTextStyles :: Map.Map (Set.Set TextStyle)
|
||||||
|
(String, Doc Text)
|
||||||
, stTextStyleAttr :: Set.Set TextStyle
|
, stTextStyleAttr :: Set.Set TextStyle
|
||||||
, stIndentPara :: Int
|
, stIndentPara :: Int
|
||||||
, stInDefinition :: Bool
|
, stInDefinition :: Bool
|
||||||
|
@ -83,19 +84,20 @@ defaultWriterState =
|
||||||
, stImageCaptionId = 1
|
, stImageCaptionId = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
when :: Bool -> Doc -> Doc
|
when :: Bool -> Doc Text -> Doc Text
|
||||||
when p a = if p then a else empty
|
when p a = if p then a else empty
|
||||||
|
|
||||||
addTableStyle :: PandocMonad m => Doc -> OD m ()
|
addTableStyle :: PandocMonad m => Doc Text -> OD m ()
|
||||||
addTableStyle i = modify $ \s -> s { stTableStyles = i : stTableStyles s }
|
addTableStyle i = modify $ \s -> s { stTableStyles = i : stTableStyles s }
|
||||||
|
|
||||||
addNote :: PandocMonad m => Doc -> OD m ()
|
addNote :: PandocMonad m => Doc Text -> OD m ()
|
||||||
addNote i = modify $ \s -> s { stNotes = i : stNotes s }
|
addNote i = modify $ \s -> s { stNotes = i : stNotes s }
|
||||||
|
|
||||||
addParaStyle :: PandocMonad m => Doc -> OD m ()
|
addParaStyle :: PandocMonad m => Doc Text -> OD m ()
|
||||||
addParaStyle i = modify $ \s -> s { stParaStyles = i : stParaStyles s }
|
addParaStyle i = modify $ \s -> s { stParaStyles = i : stParaStyles s }
|
||||||
|
|
||||||
addTextStyle :: PandocMonad m => Set.Set TextStyle -> (String, Doc) -> OD m ()
|
addTextStyle :: PandocMonad m
|
||||||
|
=> Set.Set TextStyle -> (String, Doc Text) -> OD m ()
|
||||||
addTextStyle attrs i = modify $ \s ->
|
addTextStyle attrs i = modify $ \s ->
|
||||||
s { stTextStyles = Map.insert attrs i (stTextStyles s) }
|
s { stTextStyles = Map.insert attrs i (stTextStyles s) }
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ setInDefinitionList b = modify $ \s -> s { stInDefinition = b }
|
||||||
setFirstPara :: PandocMonad m => OD m ()
|
setFirstPara :: PandocMonad m => OD m ()
|
||||||
setFirstPara = modify $ \s -> s { stFirstPara = True }
|
setFirstPara = modify $ \s -> s { stFirstPara = True }
|
||||||
|
|
||||||
inParagraphTags :: PandocMonad m => Doc -> OD m Doc
|
inParagraphTags :: PandocMonad m => Doc Text -> OD m (Doc Text)
|
||||||
inParagraphTags d = do
|
inParagraphTags d = do
|
||||||
b <- gets stFirstPara
|
b <- gets stFirstPara
|
||||||
a <- if b
|
a <- if b
|
||||||
|
@ -128,10 +130,10 @@ inParagraphTags d = do
|
||||||
else return [("text:style-name", "Text_20_body")]
|
else return [("text:style-name", "Text_20_body")]
|
||||||
return $ inTags False "text:p" a d
|
return $ inTags False "text:p" a d
|
||||||
|
|
||||||
inParagraphTagsWithStyle :: String -> Doc -> Doc
|
inParagraphTagsWithStyle :: String -> Doc Text -> Doc Text
|
||||||
inParagraphTagsWithStyle sty = inTags False "text:p" [("text:style-name", sty)]
|
inParagraphTagsWithStyle sty = inTags False "text:p" [("text:style-name", sty)]
|
||||||
|
|
||||||
inSpanTags :: String -> Doc -> Doc
|
inSpanTags :: String -> Doc Text -> Doc Text
|
||||||
inSpanTags s = inTags False "text:span" [("text:style-name",s)]
|
inSpanTags s = inTags False "text:span" [("text:style-name",s)]
|
||||||
|
|
||||||
withTextStyle :: PandocMonad m => TextStyle -> OD m a -> OD m a
|
withTextStyle :: PandocMonad m => TextStyle -> OD m a -> OD m a
|
||||||
|
@ -142,7 +144,7 @@ withTextStyle s f = do
|
||||||
modify $ \st -> st{ stTextStyleAttr = oldTextStyleAttr }
|
modify $ \st -> st{ stTextStyleAttr = oldTextStyleAttr }
|
||||||
return res
|
return res
|
||||||
|
|
||||||
inTextStyle :: PandocMonad m => Doc -> OD m Doc
|
inTextStyle :: PandocMonad m => Doc Text -> OD m (Doc Text)
|
||||||
inTextStyle d = do
|
inTextStyle d = do
|
||||||
at <- gets stTextStyleAttr
|
at <- gets stTextStyleAttr
|
||||||
if Set.null at
|
if Set.null at
|
||||||
|
@ -164,10 +166,10 @@ inTextStyle d = do
|
||||||
return $ inTags False
|
return $ inTags False
|
||||||
"text:span" [("text:style-name",styleName)] d
|
"text:span" [("text:style-name",styleName)] d
|
||||||
|
|
||||||
formulaStyles :: [Doc]
|
formulaStyles :: [Doc Text]
|
||||||
formulaStyles = [formulaStyle InlineMath, formulaStyle DisplayMath]
|
formulaStyles = [formulaStyle InlineMath, formulaStyle DisplayMath]
|
||||||
|
|
||||||
formulaStyle :: MathType -> Doc
|
formulaStyle :: MathType -> Doc Text
|
||||||
formulaStyle mt = inTags False "style:style"
|
formulaStyle mt = inTags False "style:style"
|
||||||
[("style:name", if mt == InlineMath then "fr1" else "fr2")
|
[("style:name", if mt == InlineMath then "fr1" else "fr2")
|
||||||
,("style:family", "graphic")
|
,("style:family", "graphic")
|
||||||
|
@ -182,7 +184,7 @@ formulaStyle mt = inTags False "style:style"
|
||||||
,("style:horizontal-rel", "paragraph-content")
|
,("style:horizontal-rel", "paragraph-content")
|
||||||
,("style:wrap", "none")]
|
,("style:wrap", "none")]
|
||||||
|
|
||||||
inHeaderTags :: PandocMonad m => Int -> String -> Doc -> OD m Doc
|
inHeaderTags :: PandocMonad m => Int -> String -> Doc Text -> OD m (Doc Text)
|
||||||
inHeaderTags i ident d =
|
inHeaderTags i ident d =
|
||||||
return $ inTags False "text:h" [ ("text:style-name", "Heading_20_" ++ show i)
|
return $ inTags False "text:h" [ ("text:style-name", "Heading_20_" ++ show i)
|
||||||
, ("text:outline-level", show i)]
|
, ("text:outline-level", show i)]
|
||||||
|
@ -192,11 +194,11 @@ inHeaderTags i ident d =
|
||||||
<> d <>
|
<> d <>
|
||||||
selfClosingTag "text:bookmark-end" [ ("text:name", ident) ]
|
selfClosingTag "text:bookmark-end" [ ("text:name", ident) ]
|
||||||
|
|
||||||
inQuotes :: QuoteType -> Doc -> Doc
|
inQuotes :: QuoteType -> Doc Text -> Doc Text
|
||||||
inQuotes SingleQuote s = char '\8216' <> s <> char '\8217'
|
inQuotes SingleQuote s = char '\8216' <> s <> char '\8217'
|
||||||
inQuotes DoubleQuote s = char '\8220' <> s <> char '\8221'
|
inQuotes DoubleQuote s = char '\8220' <> s <> char '\8221'
|
||||||
|
|
||||||
handleSpaces :: String -> Doc
|
handleSpaces :: String -> Doc Text
|
||||||
handleSpaces s
|
handleSpaces s
|
||||||
| ( ' ':_) <- s = genTag s
|
| ( ' ':_) <- s = genTag s
|
||||||
| ('\t':x) <- s = selfClosingTag "text:tab" [] <> rm x
|
| ('\t':x) <- s = selfClosingTag "text:tab" [] <> rm x
|
||||||
|
@ -220,15 +222,13 @@ writeOpenDocument opts (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
((body, metadata),s) <- flip runStateT
|
((body, metadata),s) <- flip runStateT
|
||||||
defaultWriterState $ do
|
defaultWriterState $ do
|
||||||
m <- metaToJSON opts
|
m <- metaToContext opts
|
||||||
(fmap render' . blocksToOpenDocument opts)
|
(blocksToOpenDocument opts)
|
||||||
(fmap render' . inlinesToOpenDocument opts)
|
(fmap chomp . inlinesToOpenDocument opts)
|
||||||
meta
|
meta
|
||||||
b <- render' `fmap` blocksToOpenDocument opts blocks
|
b <- blocksToOpenDocument opts blocks
|
||||||
return (b, m)
|
return (b, m)
|
||||||
let styles = stTableStyles s ++ stParaStyles s ++ formulaStyles ++
|
let styles = stTableStyles s ++ stParaStyles s ++ formulaStyles ++
|
||||||
map snd (sortBy (flip (comparing fst)) (
|
map snd (sortBy (flip (comparing fst)) (
|
||||||
|
@ -239,33 +239,34 @@ writeOpenDocument opts (Pandoc meta blocks) = do
|
||||||
let automaticStyles = vcat $ reverse $ styles ++ listStyles
|
let automaticStyles = vcat $ reverse $ styles ++ listStyles
|
||||||
let context = defField "body" body
|
let context = defField "body" body
|
||||||
$ defField "toc" (writerTableOfContents opts)
|
$ defField "toc" (writerTableOfContents opts)
|
||||||
$defField "automatic-styles" (render' automaticStyles) metadata
|
$ defField "automatic-styles" automaticStyles
|
||||||
return $
|
$ metadata
|
||||||
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> body
|
Nothing -> body
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
withParagraphStyle :: PandocMonad m
|
withParagraphStyle :: PandocMonad m
|
||||||
=> WriterOptions -> String -> [Block] -> OD m Doc
|
=> WriterOptions -> String -> [Block] -> OD m (Doc Text)
|
||||||
withParagraphStyle o s (b:bs)
|
withParagraphStyle o s (b:bs)
|
||||||
| Para l <- b = go =<< inParagraphTagsWithStyle s <$> inlinesToOpenDocument o l
|
| Para l <- b = go =<< inParagraphTagsWithStyle s <$> inlinesToOpenDocument o l
|
||||||
| otherwise = go =<< blockToOpenDocument o b
|
| otherwise = go =<< blockToOpenDocument o b
|
||||||
where go i = (<>) i <$> withParagraphStyle o s bs
|
where go i = (<>) i <$> withParagraphStyle o s bs
|
||||||
withParagraphStyle _ _ [] = return empty
|
withParagraphStyle _ _ [] = return empty
|
||||||
|
|
||||||
inPreformattedTags :: PandocMonad m => String -> OD m Doc
|
inPreformattedTags :: PandocMonad m => String -> OD m (Doc Text)
|
||||||
inPreformattedTags s = do
|
inPreformattedTags s = do
|
||||||
n <- paraStyle [("style:parent-style-name","Preformatted_20_Text")]
|
n <- paraStyle [("style:parent-style-name","Preformatted_20_Text")]
|
||||||
return . inParagraphTagsWithStyle ("P" ++ show n) . handleSpaces $ s
|
return . inParagraphTagsWithStyle ("P" ++ show n) . handleSpaces $ s
|
||||||
|
|
||||||
orderedListToOpenDocument :: PandocMonad m
|
orderedListToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> Int -> [[Block]] -> OD m Doc
|
=> WriterOptions -> Int -> [[Block]] -> OD m (Doc Text)
|
||||||
orderedListToOpenDocument o pn bs =
|
orderedListToOpenDocument o pn bs =
|
||||||
vcat . map (inTagsIndented "text:list-item") <$>
|
vcat . map (inTagsIndented "text:list-item") <$>
|
||||||
mapM (orderedItemToOpenDocument o pn . map plainToPara) bs
|
mapM (orderedItemToOpenDocument o pn . map plainToPara) bs
|
||||||
|
|
||||||
orderedItemToOpenDocument :: PandocMonad m
|
orderedItemToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> Int -> [Block] -> OD m Doc
|
=> WriterOptions -> Int -> [Block] -> OD m (Doc Text)
|
||||||
orderedItemToOpenDocument o n bs = vcat <$> mapM go bs
|
orderedItemToOpenDocument o n bs = vcat <$> mapM go bs
|
||||||
where go (OrderedList a l) = newLevel a l
|
where go (OrderedList a l) = newLevel a l
|
||||||
go (Para l) = inParagraphTagsWithStyle ("P" ++ show n) <$>
|
go (Para l) = inParagraphTagsWithStyle ("P" ++ show n) <$>
|
||||||
|
@ -294,7 +295,7 @@ newOrderedListStyle b a = do
|
||||||
return (ln,pn)
|
return (ln,pn)
|
||||||
|
|
||||||
bulletListToOpenDocument :: PandocMonad m
|
bulletListToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> [[Block]] -> OD m Doc
|
=> WriterOptions -> [[Block]] -> OD m (Doc Text)
|
||||||
bulletListToOpenDocument o b = do
|
bulletListToOpenDocument o b = do
|
||||||
ln <- (+) 1 . length <$> gets stListStyles
|
ln <- (+) 1 . length <$> gets stListStyles
|
||||||
(pn,ns) <- if isTightList b then inTightList (bulletListStyle ln) else bulletListStyle ln
|
(pn,ns) <- if isTightList b then inTightList (bulletListStyle ln) else bulletListStyle ln
|
||||||
|
@ -303,12 +304,12 @@ bulletListToOpenDocument o b = do
|
||||||
return $ inTags True "text:list" [("text:style-name", "L" ++ show ln)] is
|
return $ inTags True "text:list" [("text:style-name", "L" ++ show ln)] is
|
||||||
|
|
||||||
listItemsToOpenDocument :: PandocMonad m
|
listItemsToOpenDocument :: PandocMonad m
|
||||||
=> String -> WriterOptions -> [[Block]] -> OD m Doc
|
=> String -> WriterOptions -> [[Block]] -> OD m (Doc Text)
|
||||||
listItemsToOpenDocument s o is =
|
listItemsToOpenDocument s o is =
|
||||||
vcat . map (inTagsIndented "text:list-item") <$> mapM (withParagraphStyle o s . map plainToPara) is
|
vcat . map (inTagsIndented "text:list-item") <$> mapM (withParagraphStyle o s . map plainToPara) is
|
||||||
|
|
||||||
deflistItemToOpenDocument :: PandocMonad m
|
deflistItemToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> ([Inline],[[Block]]) -> OD m Doc
|
=> WriterOptions -> ([Inline],[[Block]]) -> OD m (Doc Text)
|
||||||
deflistItemToOpenDocument o (t,d) = do
|
deflistItemToOpenDocument o (t,d) = do
|
||||||
let ts = if isTightList d
|
let ts = if isTightList d
|
||||||
then "Definition_20_Term_20_Tight" else "Definition_20_Term"
|
then "Definition_20_Term_20_Tight" else "Definition_20_Term"
|
||||||
|
@ -319,7 +320,7 @@ deflistItemToOpenDocument o (t,d) = do
|
||||||
return $ t' $$ d'
|
return $ t' $$ d'
|
||||||
|
|
||||||
inBlockQuote :: PandocMonad m
|
inBlockQuote :: PandocMonad m
|
||||||
=> WriterOptions -> Int -> [Block] -> OD m Doc
|
=> WriterOptions -> Int -> [Block] -> OD m (Doc Text)
|
||||||
inBlockQuote o i (b:bs)
|
inBlockQuote o i (b:bs)
|
||||||
| BlockQuote l <- b = do increaseIndent
|
| BlockQuote l <- b = do increaseIndent
|
||||||
ni <- paraStyle
|
ni <- paraStyle
|
||||||
|
@ -331,11 +332,11 @@ inBlockQuote o i (b:bs)
|
||||||
inBlockQuote _ _ [] = resetIndent >> return empty
|
inBlockQuote _ _ [] = resetIndent >> return empty
|
||||||
|
|
||||||
-- | Convert a list of Pandoc blocks to OpenDocument.
|
-- | Convert a list of Pandoc blocks to OpenDocument.
|
||||||
blocksToOpenDocument :: PandocMonad m => WriterOptions -> [Block] -> OD m Doc
|
blocksToOpenDocument :: PandocMonad m => WriterOptions -> [Block] -> OD m (Doc Text)
|
||||||
blocksToOpenDocument o b = vcat <$> mapM (blockToOpenDocument o) b
|
blocksToOpenDocument o b = vcat <$> mapM (blockToOpenDocument o) b
|
||||||
|
|
||||||
-- | Convert a Pandoc block element to OpenDocument.
|
-- | Convert a Pandoc block element to OpenDocument.
|
||||||
blockToOpenDocument :: PandocMonad m => WriterOptions -> Block -> OD m Doc
|
blockToOpenDocument :: PandocMonad m => WriterOptions -> Block -> OD m (Doc Text)
|
||||||
blockToOpenDocument o bs
|
blockToOpenDocument o bs
|
||||||
| Plain b <- bs = if null b
|
| Plain b <- bs = if null b
|
||||||
then return empty
|
then return empty
|
||||||
|
@ -417,21 +418,21 @@ blockToOpenDocument o bs
|
||||||
return $ imageDoc $$ captionDoc
|
return $ imageDoc $$ captionDoc
|
||||||
|
|
||||||
|
|
||||||
numberedTableCaption :: PandocMonad m => Doc -> OD m Doc
|
numberedTableCaption :: PandocMonad m => Doc Text -> OD m (Doc Text)
|
||||||
numberedTableCaption caption = do
|
numberedTableCaption caption = do
|
||||||
id' <- gets stTableCaptionId
|
id' <- gets stTableCaptionId
|
||||||
modify (\st -> st{ stTableCaptionId = id' + 1 })
|
modify (\st -> st{ stTableCaptionId = id' + 1 })
|
||||||
capterm <- translateTerm Term.Table
|
capterm <- translateTerm Term.Table
|
||||||
return $ numberedCaption "Table" capterm "Table" id' caption
|
return $ numberedCaption "Table" capterm "Table" id' caption
|
||||||
|
|
||||||
numberedFigureCaption :: PandocMonad m => Doc -> OD m Doc
|
numberedFigureCaption :: PandocMonad m => Doc Text -> OD m (Doc Text)
|
||||||
numberedFigureCaption caption = do
|
numberedFigureCaption caption = do
|
||||||
id' <- gets stImageCaptionId
|
id' <- gets stImageCaptionId
|
||||||
modify (\st -> st{ stImageCaptionId = id' + 1 })
|
modify (\st -> st{ stImageCaptionId = id' + 1 })
|
||||||
capterm <- translateTerm Term.Figure
|
capterm <- translateTerm Term.Figure
|
||||||
return $ numberedCaption "FigureCaption" capterm "Illustration" id' caption
|
return $ numberedCaption "FigureCaption" capterm "Illustration" id' caption
|
||||||
|
|
||||||
numberedCaption :: String -> String -> String -> Int -> Doc -> Doc
|
numberedCaption :: String -> String -> String -> Int -> Doc Text -> Doc Text
|
||||||
numberedCaption style term name num caption =
|
numberedCaption style term name num caption =
|
||||||
let t = text term
|
let t = text term
|
||||||
r = num - 1
|
r = num - 1
|
||||||
|
@ -442,26 +443,26 @@ numberedCaption style term name num caption =
|
||||||
c = text ": "
|
c = text ": "
|
||||||
in inParagraphTagsWithStyle style $ hcat [ t, text " ", s, c, caption ]
|
in inParagraphTagsWithStyle style $ hcat [ t, text " ", s, c, caption ]
|
||||||
|
|
||||||
unNumberedCaption :: Monad m => String -> Doc -> OD m Doc
|
unNumberedCaption :: Monad m => String -> Doc Text -> OD m (Doc Text)
|
||||||
unNumberedCaption style caption = return $ inParagraphTagsWithStyle style caption
|
unNumberedCaption style caption = return $ inParagraphTagsWithStyle style caption
|
||||||
|
|
||||||
colHeadsToOpenDocument :: PandocMonad m
|
colHeadsToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> [String] -> [[Block]]
|
=> WriterOptions -> [String] -> [[Block]]
|
||||||
-> OD m Doc
|
-> OD m (Doc Text)
|
||||||
colHeadsToOpenDocument o ns hs =
|
colHeadsToOpenDocument o ns hs =
|
||||||
inTagsIndented "table:table-header-rows" . inTagsIndented "table:table-row" . vcat <$>
|
inTagsIndented "table:table-header-rows" . inTagsIndented "table:table-row" . vcat <$>
|
||||||
mapM (tableItemToOpenDocument o "TableHeaderRowCell") (zip ns hs)
|
mapM (tableItemToOpenDocument o "TableHeaderRowCell") (zip ns hs)
|
||||||
|
|
||||||
tableRowToOpenDocument :: PandocMonad m
|
tableRowToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> [String] -> [[Block]]
|
=> WriterOptions -> [String] -> [[Block]]
|
||||||
-> OD m Doc
|
-> OD m (Doc Text)
|
||||||
tableRowToOpenDocument o ns cs =
|
tableRowToOpenDocument o ns cs =
|
||||||
inTagsIndented "table:table-row" . vcat <$>
|
inTagsIndented "table:table-row" . vcat <$>
|
||||||
mapM (tableItemToOpenDocument o "TableRowCell") (zip ns cs)
|
mapM (tableItemToOpenDocument o "TableRowCell") (zip ns cs)
|
||||||
|
|
||||||
tableItemToOpenDocument :: PandocMonad m
|
tableItemToOpenDocument :: PandocMonad m
|
||||||
=> WriterOptions -> String -> (String,[Block])
|
=> WriterOptions -> String -> (String,[Block])
|
||||||
-> OD m Doc
|
-> OD m (Doc Text)
|
||||||
tableItemToOpenDocument o s (n,i) =
|
tableItemToOpenDocument o s (n,i) =
|
||||||
let a = [ ("table:style-name" , s )
|
let a = [ ("table:style-name" , s )
|
||||||
, ("office:value-type", "string" )
|
, ("office:value-type", "string" )
|
||||||
|
@ -470,10 +471,10 @@ tableItemToOpenDocument o s (n,i) =
|
||||||
withParagraphStyle o n (map plainToPara i)
|
withParagraphStyle o n (map plainToPara i)
|
||||||
|
|
||||||
-- | Convert a list of inline elements to OpenDocument.
|
-- | Convert a list of inline elements to OpenDocument.
|
||||||
inlinesToOpenDocument :: PandocMonad m => WriterOptions -> [Inline] -> OD m Doc
|
inlinesToOpenDocument :: PandocMonad m => WriterOptions -> [Inline] -> OD m (Doc Text)
|
||||||
inlinesToOpenDocument o l = hcat <$> toChunks o l
|
inlinesToOpenDocument o l = hcat <$> toChunks o l
|
||||||
|
|
||||||
toChunks :: PandocMonad m => WriterOptions -> [Inline] -> OD m [Doc]
|
toChunks :: PandocMonad m => WriterOptions -> [Inline] -> OD m [Doc Text]
|
||||||
toChunks _ [] = return []
|
toChunks _ [] = return []
|
||||||
toChunks o (x : xs)
|
toChunks o (x : xs)
|
||||||
| isChunkable x = do
|
| isChunkable x = do
|
||||||
|
@ -494,7 +495,7 @@ isChunkable SoftBreak = True
|
||||||
isChunkable _ = False
|
isChunkable _ = False
|
||||||
|
|
||||||
-- | Convert an inline element to OpenDocument.
|
-- | Convert an inline element to OpenDocument.
|
||||||
inlineToOpenDocument :: PandocMonad m => WriterOptions -> Inline -> OD m Doc
|
inlineToOpenDocument :: PandocMonad m => WriterOptions -> Inline -> OD m (Doc Text)
|
||||||
inlineToOpenDocument o ils
|
inlineToOpenDocument o ils
|
||||||
= case ils of
|
= case ils of
|
||||||
Space -> return space
|
Space -> return space
|
||||||
|
@ -557,7 +558,7 @@ inlineToOpenDocument o ils
|
||||||
addNote nn
|
addNote nn
|
||||||
return nn
|
return nn
|
||||||
|
|
||||||
bulletListStyle :: PandocMonad m => Int -> OD m (Int,(Int,[Doc]))
|
bulletListStyle :: PandocMonad m => Int -> OD m (Int,(Int,[Doc Text]))
|
||||||
bulletListStyle l = do
|
bulletListStyle l = do
|
||||||
let doStyles i = inTags True "text:list-level-style-bullet"
|
let doStyles i = inTags True "text:list-level-style-bullet"
|
||||||
[ ("text:level" , show (i + 1) )
|
[ ("text:level" , show (i + 1) )
|
||||||
|
@ -570,7 +571,7 @@ bulletListStyle l = do
|
||||||
pn <- paraListStyle l
|
pn <- paraListStyle l
|
||||||
return (pn, (l, listElStyle))
|
return (pn, (l, listElStyle))
|
||||||
|
|
||||||
orderedListLevelStyle :: ListAttributes -> (Int, [Doc]) -> (Int,[Doc])
|
orderedListLevelStyle :: ListAttributes -> (Int, [Doc Text]) -> (Int,[Doc Text])
|
||||||
orderedListLevelStyle (s,n, d) (l,ls) =
|
orderedListLevelStyle (s,n, d) (l,ls) =
|
||||||
let suffix = case d of
|
let suffix = case d of
|
||||||
OneParen -> [("style:num-suffix", ")")]
|
OneParen -> [("style:num-suffix", ")")]
|
||||||
|
@ -591,7 +592,7 @@ orderedListLevelStyle (s,n, d) (l,ls) =
|
||||||
] ++ suffix) (listLevelStyle (1 + length ls))
|
] ++ suffix) (listLevelStyle (1 + length ls))
|
||||||
in (l, ls ++ [listStyle])
|
in (l, ls ++ [listStyle])
|
||||||
|
|
||||||
listLevelStyle :: Int -> Doc
|
listLevelStyle :: Int -> Doc Text
|
||||||
listLevelStyle i =
|
listLevelStyle i =
|
||||||
let indent = show (0.25 + (0.25 * fromIntegral i :: Double)) in
|
let indent = show (0.25 + (0.25 * fromIntegral i :: Double)) in
|
||||||
inTags True "style:list-level-properties"
|
inTags True "style:list-level-properties"
|
||||||
|
@ -606,7 +607,7 @@ listLevelStyle i =
|
||||||
, ("fo:margin-left", indent ++ "in")
|
, ("fo:margin-left", indent ++ "in")
|
||||||
]
|
]
|
||||||
|
|
||||||
tableStyle :: Int -> [(Char,Double)] -> Doc
|
tableStyle :: Int -> [(Char,Double)] -> Doc Text
|
||||||
tableStyle num wcs =
|
tableStyle num wcs =
|
||||||
let tableId = "Table" ++ show (num + 1)
|
let tableId = "Table" ++ show (num + 1)
|
||||||
table = inTags True "style:style"
|
table = inTags True "style:style"
|
||||||
|
@ -669,7 +670,7 @@ paraListStyle l = paraStyle
|
||||||
[("style:parent-style-name","Text_20_body")
|
[("style:parent-style-name","Text_20_body")
|
||||||
,("style:list-style-name", "L" ++ show l )]
|
,("style:list-style-name", "L" ++ show l )]
|
||||||
|
|
||||||
paraTableStyles :: String -> Int -> [Alignment] -> [(String, Doc)]
|
paraTableStyles :: String -> Int -> [Alignment] -> [(String, Doc Text)]
|
||||||
paraTableStyles _ _ [] = []
|
paraTableStyles _ _ [] = []
|
||||||
paraTableStyles t s (a:xs)
|
paraTableStyles t s (a:xs)
|
||||||
| AlignRight <- a = ( pName s, res s "end" ) : paraTableStyles t (s + 1) xs
|
| AlignRight <- a = ( pName s, res s "end" ) : paraTableStyles t (s + 1) xs
|
||||||
|
|
|
@ -25,7 +25,7 @@ import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -53,31 +53,29 @@ pandocToOrg (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext opts
|
||||||
render' = render colwidth
|
blockListToOrg
|
||||||
metadata <- metaToJSON opts
|
(fmap chomp . inlineListToOrg)
|
||||||
(fmap render' . blockListToOrg)
|
|
||||||
(fmap render' . inlineListToOrg)
|
|
||||||
meta
|
meta
|
||||||
body <- blockListToOrg blocks
|
body <- blockListToOrg blocks
|
||||||
notes <- gets (reverse . stNotes) >>= notesToOrg
|
notes <- gets (reverse . stNotes) >>= notesToOrg
|
||||||
hasMath <- gets stHasMath
|
hasMath <- gets stHasMath
|
||||||
let main = render colwidth . foldl ($+$) empty $ [body, notes]
|
let main = body $+$ notes
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
. defField "math" hasMath
|
. defField "math" hasMath
|
||||||
$ metadata
|
$ metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Return Org representation of notes.
|
-- | Return Org representation of notes.
|
||||||
notesToOrg :: PandocMonad m => [[Block]] -> Org m Doc
|
notesToOrg :: PandocMonad m => [[Block]] -> Org m (Doc Text)
|
||||||
notesToOrg notes =
|
notesToOrg notes =
|
||||||
vsep <$> zipWithM noteToOrg [1..] notes
|
vsep <$> zipWithM noteToOrg [1..] notes
|
||||||
|
|
||||||
-- | Return Org representation of a note.
|
-- | Return Org representation of a note.
|
||||||
noteToOrg :: PandocMonad m => Int -> [Block] -> Org m Doc
|
noteToOrg :: PandocMonad m => Int -> [Block] -> Org m (Doc Text)
|
||||||
noteToOrg num note = do
|
noteToOrg num note = do
|
||||||
contents <- blockListToOrg note
|
contents <- blockListToOrg note
|
||||||
let marker = "[fn:" ++ show num ++ "] "
|
let marker = "[fn:" ++ show num ++ "] "
|
||||||
|
@ -99,7 +97,7 @@ isRawFormat f =
|
||||||
-- | Convert Pandoc block element to Org.
|
-- | Convert Pandoc block element to Org.
|
||||||
blockToOrg :: PandocMonad m
|
blockToOrg :: PandocMonad m
|
||||||
=> Block -- ^ Block element
|
=> Block -- ^ Block element
|
||||||
-> Org m Doc
|
-> Org m (Doc Text)
|
||||||
blockToOrg Null = return empty
|
blockToOrg Null = return empty
|
||||||
blockToOrg (Div (_,classes@(cls:_),kvs) bs) | "drawer" `elem` classes = do
|
blockToOrg (Div (_,classes@(cls:_),kvs) bs) | "drawer" `elem` classes = do
|
||||||
contents <- blockListToOrg bs
|
contents <- blockListToOrg bs
|
||||||
|
@ -198,10 +196,9 @@ blockToOrg (Table caption' _ _ headers rows) = do
|
||||||
map ((+2) . numChars) $ transpose (headers' : rawRows)
|
map ((+2) . numChars) $ transpose (headers' : rawRows)
|
||||||
-- FIXME: Org doesn't allow blocks with height more than 1.
|
-- FIXME: Org doesn't allow blocks with height more than 1.
|
||||||
let hpipeBlocks blocks = hcat [beg, middle, end]
|
let hpipeBlocks blocks = hcat [beg, middle, end]
|
||||||
where h = maximum (1 : map height blocks)
|
where sep' = vfill " | "
|
||||||
sep' = lblock 3 $ vcat (replicate h (text " | "))
|
beg = vfill "| "
|
||||||
beg = lblock 2 $ vcat (replicate h (text "| "))
|
end = vfill " |"
|
||||||
end = lblock 2 $ vcat (replicate h (text " |"))
|
|
||||||
middle = hcat $ intersperse sep' blocks
|
middle = hcat $ intersperse sep' blocks
|
||||||
let makeRow = hpipeBlocks . zipWith lblock widthsInChars
|
let makeRow = hpipeBlocks . zipWith lblock widthsInChars
|
||||||
let head' = makeRow headers'
|
let head' = makeRow headers'
|
||||||
|
@ -219,7 +216,9 @@ blockToOrg (Table caption' _ _ headers rows) = do
|
||||||
blockToOrg (BulletList items) = do
|
blockToOrg (BulletList items) = do
|
||||||
contents <- mapM bulletListItemToOrg items
|
contents <- mapM bulletListItemToOrg items
|
||||||
-- ensure that sublists have preceding blank line
|
-- ensure that sublists have preceding blank line
|
||||||
return $ blankline $+$ vcat contents $$ blankline
|
return $ blankline $$
|
||||||
|
(if isTightList items then vcat else vsep) contents $$
|
||||||
|
blankline
|
||||||
blockToOrg (OrderedList (start, _, delim) items) = do
|
blockToOrg (OrderedList (start, _, delim) items) = do
|
||||||
let delim' = case delim of
|
let delim' = case delim of
|
||||||
TwoParens -> OneParen
|
TwoParens -> OneParen
|
||||||
|
@ -231,36 +230,48 @@ blockToOrg (OrderedList (start, _, delim) items) = do
|
||||||
in m ++ replicate s ' ') markers
|
in m ++ replicate s ' ') markers
|
||||||
contents <- zipWithM orderedListItemToOrg markers' items
|
contents <- zipWithM orderedListItemToOrg markers' items
|
||||||
-- ensure that sublists have preceding blank line
|
-- ensure that sublists have preceding blank line
|
||||||
return $ blankline $$ vcat contents $$ blankline
|
return $ blankline $$
|
||||||
|
(if isTightList items then vcat else vsep) contents $$
|
||||||
|
blankline
|
||||||
blockToOrg (DefinitionList items) = do
|
blockToOrg (DefinitionList items) = do
|
||||||
contents <- mapM definitionListItemToOrg items
|
contents <- mapM definitionListItemToOrg items
|
||||||
return $ vcat contents $$ blankline
|
return $ vcat contents $$ blankline
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to Org.
|
-- | Convert bullet list item (list of blocks) to Org.
|
||||||
bulletListItemToOrg :: PandocMonad m => [Block] -> Org m Doc
|
bulletListItemToOrg :: PandocMonad m => [Block] -> Org m (Doc Text)
|
||||||
bulletListItemToOrg items = do
|
bulletListItemToOrg items = do
|
||||||
contents <- blockListToOrg items
|
contents <- blockListToOrg items
|
||||||
return $ hang 2 "- " (contents <> cr)
|
return $ hang 2 "- " contents $$
|
||||||
|
if endsWithPlain items
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
|
|
||||||
-- | Convert ordered list item (a list of blocks) to Org.
|
-- | Convert ordered list item (a list of blocks) to Org.
|
||||||
orderedListItemToOrg :: PandocMonad m
|
orderedListItemToOrg :: PandocMonad m
|
||||||
=> String -- ^ marker for list item
|
=> String -- ^ marker for list item
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> Org m Doc
|
-> Org m (Doc Text)
|
||||||
orderedListItemToOrg marker items = do
|
orderedListItemToOrg marker items = do
|
||||||
contents <- blockListToOrg items
|
contents <- blockListToOrg items
|
||||||
return $ hang (length marker + 1) (text marker <> space) (contents <> cr)
|
return $ hang (length marker + 1) (text marker <> space) contents $$
|
||||||
|
if endsWithPlain items
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert definition list item (label, list of blocks) to Org.
|
-- | Convert definition list item (label, list of blocks) to Org.
|
||||||
definitionListItemToOrg :: PandocMonad m
|
definitionListItemToOrg :: PandocMonad m
|
||||||
=> ([Inline], [[Block]]) -> Org m Doc
|
=> ([Inline], [[Block]]) -> Org m (Doc Text)
|
||||||
definitionListItemToOrg (label, defs) = do
|
definitionListItemToOrg (label, defs) = do
|
||||||
label' <- inlineListToOrg label
|
label' <- inlineListToOrg label
|
||||||
contents <- vcat <$> mapM blockListToOrg defs
|
contents <- vcat <$> mapM blockListToOrg defs
|
||||||
return . hang 2 "- " $ label' <> " :: " <> (contents <> cr)
|
return $ hang 2 "- " (label' <> " :: " <> contents) $$
|
||||||
|
if isTightList defs
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert list of key/value pairs to Org :PROPERTIES: drawer.
|
-- | Convert list of key/value pairs to Org :PROPERTIES: drawer.
|
||||||
propertiesDrawer :: Attr -> Doc
|
propertiesDrawer :: Attr -> Doc Text
|
||||||
propertiesDrawer (ident, classes, kv) =
|
propertiesDrawer (ident, classes, kv) =
|
||||||
let
|
let
|
||||||
drawerStart = text ":PROPERTIES:"
|
drawerStart = text ":PROPERTIES:"
|
||||||
|
@ -271,11 +282,11 @@ propertiesDrawer (ident, classes, kv) =
|
||||||
in
|
in
|
||||||
drawerStart <> cr <> properties <> cr <> drawerEnd
|
drawerStart <> cr <> properties <> cr <> drawerEnd
|
||||||
where
|
where
|
||||||
kvToOrgProperty :: (String, String) -> Doc
|
kvToOrgProperty :: (String, String) -> Doc Text
|
||||||
kvToOrgProperty (key, value) =
|
kvToOrgProperty (key, value) =
|
||||||
text ":" <> text key <> text ": " <> text value <> cr
|
text ":" <> text key <> text ": " <> text value <> cr
|
||||||
|
|
||||||
attrHtml :: Attr -> Doc
|
attrHtml :: Attr -> Doc Text
|
||||||
attrHtml ("" , [] , []) = mempty
|
attrHtml ("" , [] , []) = mempty
|
||||||
attrHtml (ident, classes, kvs) =
|
attrHtml (ident, classes, kvs) =
|
||||||
let
|
let
|
||||||
|
@ -288,13 +299,13 @@ attrHtml (ident, classes, kvs) =
|
||||||
-- | Convert list of Pandoc block elements to Org.
|
-- | Convert list of Pandoc block elements to Org.
|
||||||
blockListToOrg :: PandocMonad m
|
blockListToOrg :: PandocMonad m
|
||||||
=> [Block] -- ^ List of block elements
|
=> [Block] -- ^ List of block elements
|
||||||
-> Org m Doc
|
-> Org m (Doc Text)
|
||||||
blockListToOrg blocks = vcat <$> mapM blockToOrg blocks
|
blockListToOrg blocks = vcat <$> mapM blockToOrg blocks
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to Org.
|
-- | Convert list of Pandoc inline elements to Org.
|
||||||
inlineListToOrg :: PandocMonad m
|
inlineListToOrg :: PandocMonad m
|
||||||
=> [Inline]
|
=> [Inline]
|
||||||
-> Org m Doc
|
-> Org m (Doc Text)
|
||||||
inlineListToOrg lst = hcat <$> mapM inlineToOrg (fixMarkers lst)
|
inlineListToOrg lst = hcat <$> mapM inlineToOrg (fixMarkers lst)
|
||||||
where fixMarkers [] = [] -- prevent note refs and list markers from wrapping, see #4171
|
where fixMarkers [] = [] -- prevent note refs and list markers from wrapping, see #4171
|
||||||
fixMarkers (Space : x : rest) | shouldFix x =
|
fixMarkers (Space : x : rest) | shouldFix x =
|
||||||
|
@ -309,7 +320,7 @@ inlineListToOrg lst = hcat <$> mapM inlineToOrg (fixMarkers lst)
|
||||||
shouldFix _ = False
|
shouldFix _ = False
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to Org.
|
-- | Convert Pandoc inline element to Org.
|
||||||
inlineToOrg :: PandocMonad m => Inline -> Org m Doc
|
inlineToOrg :: PandocMonad m => Inline -> Org m (Doc Text)
|
||||||
inlineToOrg (Span (uid, [], []) []) =
|
inlineToOrg (Span (uid, [], []) []) =
|
||||||
return $ "<<" <> text uid <> ">>"
|
return $ "<<" <> text uid <> ">>"
|
||||||
inlineToOrg (Span _ lst) =
|
inlineToOrg (Span _ lst) =
|
||||||
|
|
|
@ -17,16 +17,17 @@ module Text.Pandoc.Writers.RST ( writeRST, flatten ) where
|
||||||
import Prelude
|
import Prelude
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
import Data.Char (isSpace, toLower)
|
import Data.Char (isSpace, toLower)
|
||||||
import Data.List (isPrefixOf, stripPrefix, transpose)
|
import Data.List (isPrefixOf, stripPrefix, transpose, intersperse)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Text (Text, stripEnd)
|
import qualified Data.Text as T
|
||||||
|
import Data.Text (Text)
|
||||||
import qualified Text.Pandoc.Builder as B
|
import qualified Text.Pandoc.Builder as B
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -62,13 +63,11 @@ pandocToRST (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText opts == WrapAuto
|
let colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
let subtit = lookupMetaInlines "subtitle" meta
|
let subtit = lookupMetaInlines "subtitle" meta
|
||||||
title <- titleToRST (docTitle meta) subtit
|
title <- titleToRST (docTitle meta) subtit
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap render' . blockListToRST)
|
blockListToRST
|
||||||
(fmap (stripEnd . render') . inlineListToRST)
|
(fmap chomp . inlineListToRST)
|
||||||
meta
|
meta
|
||||||
body <- blockListToRST' True $ case writerTemplate opts of
|
body <- blockListToRST' True $ case writerTemplate opts of
|
||||||
Just _ -> normalizeHeadings 1 blocks
|
Just _ -> normalizeHeadings 1 blocks
|
||||||
|
@ -79,16 +78,16 @@ pandocToRST (Pandoc meta blocks) = do
|
||||||
pics <- gets (reverse . stImages) >>= pictRefsToRST
|
pics <- gets (reverse . stImages) >>= pictRefsToRST
|
||||||
hasMath <- gets stHasMath
|
hasMath <- gets stHasMath
|
||||||
rawTeX <- gets stHasRawTeX
|
rawTeX <- gets stHasRawTeX
|
||||||
let main = render' $ foldl ($+$) empty [body, notes, refs, pics]
|
let main = vsep [body, notes, refs, pics]
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "toc" (writerTableOfContents opts)
|
$ defField "toc" (writerTableOfContents opts)
|
||||||
$ defField "toc-depth" (show $ writerTOCDepth opts)
|
$ defField "toc-depth" (T.pack $ show $ writerTOCDepth opts)
|
||||||
$ defField "number-sections" (writerNumberSections opts)
|
$ defField "number-sections" (writerNumberSections opts)
|
||||||
$ defField "math" hasMath
|
$ defField "math" hasMath
|
||||||
$ defField "titleblock" (render Nothing title :: String)
|
$ defField "titleblock" (render Nothing title :: Text)
|
||||||
$ defField "math" hasMath
|
$ defField "math" hasMath
|
||||||
$ defField "rawtex" rawTeX metadata
|
$ defField "rawtex" rawTeX metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -102,26 +101,26 @@ pandocToRST (Pandoc meta blocks) = do
|
||||||
normalizeHeadings _ [] = []
|
normalizeHeadings _ [] = []
|
||||||
|
|
||||||
-- | Return RST representation of reference key table.
|
-- | Return RST representation of reference key table.
|
||||||
refsToRST :: PandocMonad m => Refs -> RST m Doc
|
refsToRST :: PandocMonad m => Refs -> RST m (Doc Text)
|
||||||
refsToRST refs = mapM keyToRST refs >>= return . vcat
|
refsToRST refs = mapM keyToRST refs >>= return . vcat
|
||||||
|
|
||||||
-- | Return RST representation of a reference key.
|
-- | Return RST representation of a reference key.
|
||||||
keyToRST :: PandocMonad m => ([Inline], (String, String)) -> RST m Doc
|
keyToRST :: PandocMonad m => ([Inline], (String, String)) -> RST m (Doc Text)
|
||||||
keyToRST (label, (src, _)) = do
|
keyToRST (label, (src, _)) = do
|
||||||
label' <- inlineListToRST label
|
label' <- inlineListToRST label
|
||||||
let label'' = if ':' `elem` (render Nothing label' :: String)
|
let label'' = if (==':') `T.any` (render Nothing label' :: Text)
|
||||||
then char '`' <> label' <> char '`'
|
then char '`' <> label' <> char '`'
|
||||||
else label'
|
else label'
|
||||||
return $ nowrap $ ".. _" <> label'' <> ": " <> text src
|
return $ nowrap $ ".. _" <> label'' <> ": " <> text src
|
||||||
|
|
||||||
-- | Return RST representation of notes.
|
-- | Return RST representation of notes.
|
||||||
notesToRST :: PandocMonad m => [[Block]] -> RST m Doc
|
notesToRST :: PandocMonad m => [[Block]] -> RST m (Doc Text)
|
||||||
notesToRST notes =
|
notesToRST notes =
|
||||||
zipWithM noteToRST [1..] notes >>=
|
zipWithM noteToRST [1..] notes >>=
|
||||||
return . vsep
|
return . vsep
|
||||||
|
|
||||||
-- | Return RST representation of a note.
|
-- | Return RST representation of a note.
|
||||||
noteToRST :: PandocMonad m => Int -> [Block] -> RST m Doc
|
noteToRST :: PandocMonad m => Int -> [Block] -> RST m (Doc Text)
|
||||||
noteToRST num note = do
|
noteToRST num note = do
|
||||||
contents <- blockListToRST note
|
contents <- blockListToRST note
|
||||||
let marker = ".. [" <> text (show num) <> "]"
|
let marker = ".. [" <> text (show num) <> "]"
|
||||||
|
@ -130,13 +129,13 @@ noteToRST num note = do
|
||||||
-- | Return RST representation of picture reference table.
|
-- | Return RST representation of picture reference table.
|
||||||
pictRefsToRST :: PandocMonad m
|
pictRefsToRST :: PandocMonad m
|
||||||
=> [([Inline], (Attr, String, String, Maybe String))]
|
=> [([Inline], (Attr, String, String, Maybe String))]
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
pictRefsToRST refs = mapM pictToRST refs >>= return . vcat
|
pictRefsToRST refs = mapM pictToRST refs >>= return . vcat
|
||||||
|
|
||||||
-- | Return RST representation of a picture substitution reference.
|
-- | Return RST representation of a picture substitution reference.
|
||||||
pictToRST :: PandocMonad m
|
pictToRST :: PandocMonad m
|
||||||
=> ([Inline], (Attr, String, String, Maybe String))
|
=> ([Inline], (Attr, String, String, Maybe String))
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
pictToRST (label, (attr, src, _, mbtarget)) = do
|
pictToRST (label, (attr, src, _, mbtarget)) = do
|
||||||
label' <- inlineListToRST label
|
label' <- inlineListToRST label
|
||||||
dims <- imageDimsToRST attr
|
dims <- imageDimsToRST attr
|
||||||
|
@ -171,14 +170,14 @@ escapeString = escapeString' True
|
||||||
_ -> '.':escapeString' False opts cs
|
_ -> '.':escapeString' False opts cs
|
||||||
_ -> c : escapeString' False opts cs
|
_ -> c : escapeString' False opts cs
|
||||||
|
|
||||||
titleToRST :: PandocMonad m => [Inline] -> [Inline] -> RST m Doc
|
titleToRST :: PandocMonad m => [Inline] -> [Inline] -> RST m (Doc Text)
|
||||||
titleToRST [] _ = return empty
|
titleToRST [] _ = return empty
|
||||||
titleToRST tit subtit = do
|
titleToRST tit subtit = do
|
||||||
title <- inlineListToRST tit
|
title <- inlineListToRST tit
|
||||||
subtitle <- inlineListToRST subtit
|
subtitle <- inlineListToRST subtit
|
||||||
return $ bordered title '=' $$ bordered subtitle '-'
|
return $ bordered title '=' $$ bordered subtitle '-'
|
||||||
|
|
||||||
bordered :: Doc -> Char -> Doc
|
bordered :: Doc Text -> Char -> Doc Text
|
||||||
bordered contents c =
|
bordered contents c =
|
||||||
if len > 0
|
if len > 0
|
||||||
then border $$ contents $$ border
|
then border $$ contents $$ border
|
||||||
|
@ -189,7 +188,7 @@ bordered contents c =
|
||||||
-- | Convert Pandoc block element to RST.
|
-- | Convert Pandoc block element to RST.
|
||||||
blockToRST :: PandocMonad m
|
blockToRST :: PandocMonad m
|
||||||
=> Block -- ^ Block element
|
=> Block -- ^ Block element
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
blockToRST Null = return empty
|
blockToRST Null = return empty
|
||||||
blockToRST (Div ("",["admonition-title"],[]) _) = return empty
|
blockToRST (Div ("",["admonition-title"],[]) _) = return empty
|
||||||
-- this is generated by the rst reader and can safely be
|
-- this is generated by the rst reader and can safely be
|
||||||
|
@ -301,7 +300,9 @@ blockToRST (Table caption aligns widths headers rows) = do
|
||||||
blockToRST (BulletList items) = do
|
blockToRST (BulletList items) = do
|
||||||
contents <- mapM bulletListItemToRST items
|
contents <- mapM bulletListItemToRST items
|
||||||
-- ensure that sublists have preceding blank line
|
-- ensure that sublists have preceding blank line
|
||||||
return $ blankline $$ chomp (vcat contents) $$ blankline
|
return $ blankline $$
|
||||||
|
(if isTightList items then vcat else vsep) contents $$
|
||||||
|
blankline
|
||||||
blockToRST (OrderedList (start, style', delim) items) = do
|
blockToRST (OrderedList (start, style', delim) items) = do
|
||||||
let markers = if start == 1 && style' == DefaultStyle && delim == DefaultDelim
|
let markers = if start == 1 && style' == DefaultStyle && delim == DefaultDelim
|
||||||
then replicate (length items) "#."
|
then replicate (length items) "#."
|
||||||
|
@ -312,37 +313,48 @@ blockToRST (OrderedList (start, style', delim) items) = do
|
||||||
in m ++ replicate s ' ') markers
|
in m ++ replicate s ' ') markers
|
||||||
contents <- zipWithM orderedListItemToRST markers' items
|
contents <- zipWithM orderedListItemToRST markers' items
|
||||||
-- ensure that sublists have preceding blank line
|
-- ensure that sublists have preceding blank line
|
||||||
return $ blankline $$ chomp (vcat contents) $$ blankline
|
return $ blankline $$
|
||||||
|
(if isTightList items then vcat else vsep) contents $$
|
||||||
|
blankline
|
||||||
blockToRST (DefinitionList items) = do
|
blockToRST (DefinitionList items) = do
|
||||||
contents <- mapM definitionListItemToRST items
|
contents <- mapM definitionListItemToRST items
|
||||||
-- ensure that sublists have preceding blank line
|
-- ensure that sublists have preceding blank line
|
||||||
return $ blankline $$ chomp (vcat contents) $$ blankline
|
return $ blankline $$ vcat contents $$ blankline
|
||||||
|
|
||||||
-- | Convert bullet list item (list of blocks) to RST.
|
-- | Convert bullet list item (list of blocks) to RST.
|
||||||
bulletListItemToRST :: PandocMonad m => [Block] -> RST m Doc
|
bulletListItemToRST :: PandocMonad m => [Block] -> RST m (Doc Text)
|
||||||
bulletListItemToRST items = do
|
bulletListItemToRST items = do
|
||||||
contents <- blockListToRST items
|
contents <- blockListToRST items
|
||||||
return $ hang 3 "- " $ contents <> cr
|
return $ hang 3 "- " contents $$
|
||||||
|
if endsWithPlain items
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert ordered list item (a list of blocks) to RST.
|
-- | Convert ordered list item (a list of blocks) to RST.
|
||||||
orderedListItemToRST :: PandocMonad m
|
orderedListItemToRST :: PandocMonad m
|
||||||
=> String -- ^ marker for list item
|
=> String -- ^ marker for list item
|
||||||
-> [Block] -- ^ list item (list of blocks)
|
-> [Block] -- ^ list item (list of blocks)
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
orderedListItemToRST marker items = do
|
orderedListItemToRST marker items = do
|
||||||
contents <- blockListToRST items
|
contents <- blockListToRST items
|
||||||
let marker' = marker ++ " "
|
let marker' = marker ++ " "
|
||||||
return $ hang (length marker') (text marker') $ contents <> cr
|
return $ hang (length marker') (text marker') contents $$
|
||||||
|
if endsWithPlain items
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Convert definition list item (label, list of blocks) to RST.
|
-- | Convert definition list item (label, list of blocks) to RST.
|
||||||
definitionListItemToRST :: PandocMonad m => ([Inline], [[Block]]) -> RST m Doc
|
definitionListItemToRST :: PandocMonad m => ([Inline], [[Block]]) -> RST m (Doc Text)
|
||||||
definitionListItemToRST (label, defs) = do
|
definitionListItemToRST (label, defs) = do
|
||||||
label' <- inlineListToRST label
|
label' <- inlineListToRST label
|
||||||
contents <- liftM vcat $ mapM blockListToRST defs
|
contents <- liftM vcat $ mapM blockListToRST defs
|
||||||
return $ nowrap label' $$ nest 3 (nestle contents <> cr)
|
return $ nowrap label' $$ nest 3 (nestle contents) $$
|
||||||
|
if isTightList defs
|
||||||
|
then cr
|
||||||
|
else blankline
|
||||||
|
|
||||||
-- | Format a list of lines as line block.
|
-- | Format a list of lines as line block.
|
||||||
linesToLineBlock :: PandocMonad m => [[Inline]] -> RST m Doc
|
linesToLineBlock :: PandocMonad m => [[Inline]] -> RST m (Doc Text)
|
||||||
linesToLineBlock inlineLines = do
|
linesToLineBlock inlineLines = do
|
||||||
lns <- mapM inlineListToRST inlineLines
|
lns <- mapM inlineListToRST inlineLines
|
||||||
return $
|
return $
|
||||||
|
@ -352,7 +364,7 @@ linesToLineBlock inlineLines = do
|
||||||
blockListToRST' :: PandocMonad m
|
blockListToRST' :: PandocMonad m
|
||||||
=> Bool
|
=> Bool
|
||||||
-> [Block] -- ^ List of block elements
|
-> [Block] -- ^ List of block elements
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
blockListToRST' topLevel blocks = do
|
blockListToRST' topLevel blocks = do
|
||||||
-- insert comment between list and quoted blocks, see #4248 and #3675
|
-- insert comment between list and quoted blocks, see #4248 and #3675
|
||||||
let fixBlocks (b1:b2@(BlockQuote _):bs)
|
let fixBlocks (b1:b2@(BlockQuote _):bs)
|
||||||
|
@ -376,7 +388,7 @@ blockListToRST' topLevel blocks = do
|
||||||
|
|
||||||
blockListToRST :: PandocMonad m
|
blockListToRST :: PandocMonad m
|
||||||
=> [Block] -- ^ List of block elements
|
=> [Block] -- ^ List of block elements
|
||||||
-> RST m Doc
|
-> RST m (Doc Text)
|
||||||
blockListToRST = blockListToRST' False
|
blockListToRST = blockListToRST' False
|
||||||
|
|
||||||
transformInlines :: [Inline] -> [Inline]
|
transformInlines :: [Inline] -> [Inline]
|
||||||
|
@ -532,15 +544,15 @@ setInlineChildren (Image a _ t) i = Image a i t
|
||||||
setInlineChildren (Span a _) i = Span a i
|
setInlineChildren (Span a _) i = Span a i
|
||||||
setInlineChildren leaf _ = leaf
|
setInlineChildren leaf _ = leaf
|
||||||
|
|
||||||
inlineListToRST :: PandocMonad m => [Inline] -> RST m Doc
|
inlineListToRST :: PandocMonad m => [Inline] -> RST m (Doc Text)
|
||||||
inlineListToRST = writeInlines . walk transformInlines
|
inlineListToRST = writeInlines . walk transformInlines
|
||||||
|
|
||||||
-- | Convert list of Pandoc inline elements to RST.
|
-- | Convert list of Pandoc inline elements to RST.
|
||||||
writeInlines :: PandocMonad m => [Inline] -> RST m Doc
|
writeInlines :: PandocMonad m => [Inline] -> RST m (Doc Text)
|
||||||
writeInlines lst = mapM inlineToRST lst >>= return . hcat
|
writeInlines lst = mapM inlineToRST lst >>= return . hcat
|
||||||
|
|
||||||
-- | Convert Pandoc inline element to RST.
|
-- | Convert Pandoc inline element to RST.
|
||||||
inlineToRST :: PandocMonad m => Inline -> RST m Doc
|
inlineToRST :: PandocMonad m => Inline -> RST m (Doc Text)
|
||||||
inlineToRST (Span (_,_,kvs) ils) = do
|
inlineToRST (Span (_,_,kvs) ils) = do
|
||||||
contents <- writeInlines ils
|
contents <- writeInlines ils
|
||||||
return $
|
return $
|
||||||
|
@ -653,7 +665,7 @@ inlineToRST (Note contents) = do
|
||||||
let ref = show $ length notes + 1
|
let ref = show $ length notes + 1
|
||||||
return $ " [" <> text ref <> "]_"
|
return $ " [" <> text ref <> "]_"
|
||||||
|
|
||||||
registerImage :: PandocMonad m => Attr -> [Inline] -> Target -> Maybe String -> RST m Doc
|
registerImage :: PandocMonad m => Attr -> [Inline] -> Target -> Maybe String -> RST m (Doc Text)
|
||||||
registerImage attr alt (src,tit) mbtarget = do
|
registerImage attr alt (src,tit) mbtarget = do
|
||||||
pics <- gets stImages
|
pics <- gets stImages
|
||||||
txt <- case lookup alt pics of
|
txt <- case lookup alt pics of
|
||||||
|
@ -668,7 +680,7 @@ registerImage attr alt (src,tit) mbtarget = do
|
||||||
return alt'
|
return alt'
|
||||||
inlineListToRST txt
|
inlineListToRST txt
|
||||||
|
|
||||||
imageDimsToRST :: PandocMonad m => Attr -> RST m Doc
|
imageDimsToRST :: PandocMonad m => Attr -> RST m (Doc Text)
|
||||||
imageDimsToRST attr = do
|
imageDimsToRST attr = do
|
||||||
let (ident, _, _) = attr
|
let (ident, _, _) = attr
|
||||||
name = if null ident
|
name = if null ident
|
||||||
|
@ -686,10 +698,10 @@ imageDimsToRST attr = do
|
||||||
|
|
||||||
simpleTable :: PandocMonad m
|
simpleTable :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> (WriterOptions -> [Block] -> m Doc)
|
-> (WriterOptions -> [Block] -> m (Doc Text))
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> [[[Block]]]
|
-> [[[Block]]]
|
||||||
-> m Doc
|
-> m (Doc Text)
|
||||||
simpleTable opts blocksToDoc headers rows = do
|
simpleTable opts blocksToDoc headers rows = do
|
||||||
-- can't have empty cells in first column:
|
-- can't have empty cells in first column:
|
||||||
let fixEmpties (d:ds) = if isEmpty d
|
let fixEmpties (d:ds) = if isEmpty d
|
||||||
|
@ -703,7 +715,7 @@ simpleTable opts blocksToDoc headers rows = do
|
||||||
let numChars [] = 0
|
let numChars [] = 0
|
||||||
numChars xs = maximum . map offset $ xs
|
numChars xs = maximum . map offset $ xs
|
||||||
let colWidths = map numChars $ transpose (headerDocs : rowDocs)
|
let colWidths = map numChars $ transpose (headerDocs : rowDocs)
|
||||||
let toRow = hsep . zipWith lblock colWidths
|
let toRow = mconcat . intersperse (lblock 1 " ") . zipWith lblock colWidths
|
||||||
let hline = nowrap $ hsep (map (\n -> text (replicate n '=')) colWidths)
|
let hline = nowrap $ hsep (map (\n -> text (replicate n '=')) colWidths)
|
||||||
let hdr = if all null headers
|
let hdr = if all null headers
|
||||||
then mempty
|
then mempty
|
||||||
|
|
|
@ -96,7 +96,7 @@ writeRTF options doc = do
|
||||||
. M.adjust toPlain "author"
|
. M.adjust toPlain "author"
|
||||||
. M.adjust toPlain "date"
|
. M.adjust toPlain "date"
|
||||||
$ metamap
|
$ metamap
|
||||||
metadata <- metaToJSON options
|
metadata <- metaToContext options
|
||||||
(fmap concat . mapM (blockToRTF 0 AlignDefault))
|
(fmap concat . mapM (blockToRTF 0 AlignDefault))
|
||||||
inlinesToRTF
|
inlinesToRTF
|
||||||
meta'
|
meta'
|
||||||
|
@ -112,11 +112,10 @@ writeRTF options doc = do
|
||||||
-- of the toc rather than a boolean:
|
-- of the toc rather than a boolean:
|
||||||
. defField "toc" toc
|
. defField "toc" toc
|
||||||
else id) metadata
|
else id) metadata
|
||||||
return $
|
return $ T.pack $
|
||||||
case writerTemplate options of
|
case writerTemplate options of
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
Nothing -> T.pack $
|
Nothing -> case reverse body of
|
||||||
case reverse body of
|
|
||||||
('\n':_) -> body
|
('\n':_) -> body
|
||||||
_ -> body ++ "\n"
|
_ -> body ++ "\n"
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,11 @@ import Prelude
|
||||||
import Data.Char (ord, isAscii)
|
import Data.Char (ord, isAscii)
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
|
import Data.String
|
||||||
import Data.Maybe (fromMaybe, isJust, catMaybes)
|
import Data.Maybe (fromMaybe, isJust, catMaybes)
|
||||||
import Text.Pandoc.Class (PandocMonad)
|
import Text.Pandoc.Class (PandocMonad)
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
import Text.Pandoc.RoffChar (standardEscapes,
|
import Text.Pandoc.RoffChar (standardEscapes,
|
||||||
characterCodes, combiningAccents)
|
characterCodes, combiningAccents)
|
||||||
|
@ -97,7 +98,7 @@ escapeString escapeMode (x:xs) =
|
||||||
characterCodeMap :: Map.Map Char String
|
characterCodeMap :: Map.Map Char String
|
||||||
characterCodeMap = Map.fromList characterCodes
|
characterCodeMap = Map.fromList characterCodes
|
||||||
|
|
||||||
fontChange :: PandocMonad m => MS m Doc
|
fontChange :: (IsString a, PandocMonad m) => MS m (Doc a)
|
||||||
fontChange = do
|
fontChange = do
|
||||||
features <- gets stFontFeatures
|
features <- gets stFontFeatures
|
||||||
inHeader <- gets stInHeader
|
inHeader <- gets stInHeader
|
||||||
|
@ -110,7 +111,8 @@ fontChange = do
|
||||||
then text "\\f[R]"
|
then text "\\f[R]"
|
||||||
else text $ "\\f[" ++ filling ++ "]"
|
else text $ "\\f[" ++ filling ++ "]"
|
||||||
|
|
||||||
withFontFeature :: PandocMonad m => Char -> MS m Doc -> MS m Doc
|
withFontFeature :: (IsString a, PandocMonad m)
|
||||||
|
=> Char -> MS m (Doc a) -> MS m (Doc a)
|
||||||
withFontFeature c action = do
|
withFontFeature c action = do
|
||||||
modify $ \st -> st{ stFontFeatures = Map.adjust not c $ stFontFeatures st }
|
modify $ \st -> st{ stFontFeatures = Map.adjust not c $ stFontFeatures st }
|
||||||
begin <- fontChange
|
begin <- fontChange
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{- |
|
{- |
|
||||||
|
@ -13,9 +14,9 @@
|
||||||
Shared utility functions for pandoc writers.
|
Shared utility functions for pandoc writers.
|
||||||
-}
|
-}
|
||||||
module Text.Pandoc.Writers.Shared (
|
module Text.Pandoc.Writers.Shared (
|
||||||
metaToJSON
|
metaToContext
|
||||||
, metaToJSON'
|
, metaToContext'
|
||||||
, addVariablesToJSON
|
, addVariablesToContext
|
||||||
, getField
|
, getField
|
||||||
, setField
|
, setField
|
||||||
, resetField
|
, resetField
|
||||||
|
@ -33,149 +34,118 @@ module Text.Pandoc.Writers.Shared (
|
||||||
, toSubscript
|
, toSubscript
|
||||||
, toSuperscript
|
, toSuperscript
|
||||||
, toTableOfContents
|
, toTableOfContents
|
||||||
|
, endsWithPlain
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Prelude
|
import Prelude
|
||||||
|
import Safe (lastMay)
|
||||||
import Control.Monad (zipWithM)
|
import Control.Monad (zipWithM)
|
||||||
import qualified Data.Aeson as Aeson
|
import Data.Aeson (ToJSON (..), encode)
|
||||||
import Data.Aeson (FromJSON (..), Result (..), ToJSON (..), Value (Object),
|
|
||||||
encode, fromJSON)
|
|
||||||
import Data.Char (chr, ord, isSpace)
|
import Data.Char (chr, ord, isSpace)
|
||||||
import qualified Data.HashMap.Strict as H
|
|
||||||
import Data.List (groupBy, intersperse, transpose, foldl')
|
import Data.List (groupBy, intersperse, transpose, foldl')
|
||||||
import Data.Scientific (Scientific)
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Maybe (isJust)
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Traversable as Traversable
|
|
||||||
import qualified Text.Pandoc.Builder as Builder
|
import qualified Text.Pandoc.Builder as Builder
|
||||||
import Text.Pandoc.Definition
|
import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared (stringify, hierarchicalize, Element(..), deNote,
|
import Text.Pandoc.Shared (stringify, hierarchicalize, Element(..), deNote)
|
||||||
safeRead)
|
|
||||||
import Text.Pandoc.Walk (walk)
|
import Text.Pandoc.Walk (walk)
|
||||||
import Text.Pandoc.UTF8 (toStringLazy)
|
import qualified Text.Pandoc.UTF8 as UTF8
|
||||||
import Text.Pandoc.XML (escapeStringForXML)
|
import Text.Pandoc.XML (escapeStringForXML)
|
||||||
|
import Text.DocTemplates (Context(..), Val(..), TemplateTarget(..),
|
||||||
|
ToContext(..), FromContext(..))
|
||||||
|
|
||||||
-- | Create JSON value for template from a 'Meta' and an association list
|
-- | Create template Context from a 'Meta' and an association list
|
||||||
-- of variables, specified at the command line or in the writer.
|
-- of variables, specified at the command line or in the writer.
|
||||||
-- Variables overwrite metadata fields with the same names.
|
-- Variables overwrite metadata fields with the same names.
|
||||||
-- If multiple variables are set with the same name, a list is
|
-- If multiple variables are set with the same name, a list is
|
||||||
-- assigned. Does nothing if 'writerTemplate' is Nothing.
|
-- assigned. Does nothing if 'writerTemplate' is Nothing.
|
||||||
metaToJSON :: (Monad m, ToJSON a)
|
metaToContext :: (Monad m, TemplateTarget a)
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> ([Block] -> m a)
|
-> ([Block] -> m a)
|
||||||
-> ([Inline] -> m a)
|
-> ([Inline] -> m a)
|
||||||
-> Meta
|
-> Meta
|
||||||
-> m Value
|
-> m (Context a)
|
||||||
metaToJSON opts blockWriter inlineWriter meta
|
metaToContext opts blockWriter inlineWriter meta =
|
||||||
| isJust (writerTemplate opts) =
|
case writerTemplate opts of
|
||||||
addVariablesToJSON opts <$> metaToJSON' blockWriter inlineWriter meta
|
Nothing -> return mempty
|
||||||
| otherwise = return (Object H.empty)
|
Just _ -> addVariablesToContext opts <$>
|
||||||
|
metaToContext' blockWriter inlineWriter meta
|
||||||
|
|
||||||
-- | Like 'metaToJSON', but does not include variables and is
|
-- | Like 'metaToContext, but does not include variables and is
|
||||||
-- not sensitive to 'writerTemplate'.
|
-- not sensitive to 'writerTemplate'.
|
||||||
metaToJSON' :: (Monad m, ToJSON a)
|
metaToContext' :: (Monad m, TemplateTarget a)
|
||||||
=> ([Block] -> m a)
|
=> ([Block] -> m a)
|
||||||
-> ([Inline] -> m a)
|
-> ([Inline] -> m a)
|
||||||
-> Meta
|
-> Meta
|
||||||
-> m Value
|
-> m (Context a)
|
||||||
metaToJSON' blockWriter inlineWriter (Meta metamap) = do
|
metaToContext' blockWriter inlineWriter (Meta metamap) = do
|
||||||
renderedMap <- Traversable.mapM
|
renderedMap <- mapM (metaValueToVal blockWriter inlineWriter) metamap
|
||||||
(metaValueToJSON blockWriter inlineWriter)
|
return $ Context
|
||||||
metamap
|
$ M.foldrWithKey (\k v x -> M.insert (T.pack k) v x) mempty
|
||||||
return $ M.foldrWithKey defField (Object H.empty) renderedMap
|
$ renderedMap
|
||||||
|
|
||||||
-- | Add variables to JSON object, replacing any existing values.
|
-- | Add variables to a template Context, replacing any existing values.
|
||||||
-- Also include @meta-json@, a field containing a string representation
|
addVariablesToContext :: TemplateTarget a
|
||||||
-- of the original JSON object itself, prior to addition of variables.
|
=> WriterOptions -> Context a -> Context a
|
||||||
addVariablesToJSON :: WriterOptions -> Value -> Value
|
addVariablesToContext opts (Context m1) = Context (m1 `M.union` m2)
|
||||||
addVariablesToJSON opts metadata =
|
where
|
||||||
foldl (\acc (x,y) -> setField x y acc)
|
m2 = M.fromList $ map (\(k,v)
|
||||||
(defField "meta-json" (toStringLazy $ encode metadata) (Object mempty))
|
-> (T.pack k,SimpleVal (fromText (T.pack v)))) $
|
||||||
(writerVariables opts)
|
("meta-json", jsonrep) : writerVariables opts
|
||||||
`combineMetadata` metadata
|
jsonrep = UTF8.toStringLazy $ encode $ toJSON m1
|
||||||
where combineMetadata (Object o1) (Object o2) = Object $ H.union o1 o2
|
|
||||||
combineMetadata x _ = x
|
|
||||||
|
|
||||||
metaValueToJSON :: (Monad m, ToJSON a)
|
metaValueToVal :: (Monad m, TemplateTarget a)
|
||||||
=> ([Block] -> m a)
|
=> ([Block] -> m a)
|
||||||
-> ([Inline] -> m a)
|
-> ([Inline] -> m a)
|
||||||
-> MetaValue
|
-> MetaValue
|
||||||
-> m Value
|
-> m (Val a)
|
||||||
metaValueToJSON blockWriter inlineWriter (MetaMap metamap) = toJSON <$>
|
metaValueToVal blockWriter inlineWriter (MetaMap metamap) =
|
||||||
Traversable.mapM (metaValueToJSON blockWriter inlineWriter) metamap
|
MapVal . Context . M.mapKeys T.pack <$>
|
||||||
metaValueToJSON blockWriter inlineWriter (MetaList xs) = toJSON <$>
|
mapM (metaValueToVal blockWriter inlineWriter) metamap
|
||||||
Traversable.mapM (metaValueToJSON blockWriter inlineWriter) xs
|
metaValueToVal blockWriter inlineWriter (MetaList xs) = ListVal <$>
|
||||||
metaValueToJSON _ _ (MetaBool b) = return $ toJSON b
|
mapM (metaValueToVal blockWriter inlineWriter) xs
|
||||||
metaValueToJSON _ inlineWriter (MetaString s@('0':_:_)) =
|
metaValueToVal _ _ (MetaBool True) = return $ SimpleVal $ fromText "true"
|
||||||
-- don't treat string with leading 0 as string (#5479)
|
metaValueToVal _ _ (MetaBool False) = return NullVal
|
||||||
toJSON <$> inlineWriter (Builder.toList (Builder.text s))
|
metaValueToVal _ inlineWriter (MetaString s) =
|
||||||
metaValueToJSON _ inlineWriter (MetaString s) =
|
SimpleVal <$> inlineWriter (Builder.toList (Builder.text s))
|
||||||
case safeRead s of
|
metaValueToVal blockWriter _ (MetaBlocks bs) = SimpleVal <$> blockWriter bs
|
||||||
Just (n :: Scientific) -> return $ Aeson.Number n
|
metaValueToVal _ inlineWriter (MetaInlines is) = SimpleVal <$> inlineWriter is
|
||||||
Nothing -> toJSON <$> inlineWriter (Builder.toList (Builder.text s))
|
|
||||||
metaValueToJSON blockWriter _ (MetaBlocks bs) = toJSON <$> blockWriter bs
|
|
||||||
metaValueToJSON blockWriter inlineWriter (MetaInlines [Str s]) =
|
|
||||||
metaValueToJSON blockWriter inlineWriter (MetaString s)
|
|
||||||
metaValueToJSON _ inlineWriter (MetaInlines is) = toJSON <$> inlineWriter is
|
|
||||||
|
|
||||||
-- | Retrieve a field value from a JSON object.
|
|
||||||
getField :: FromJSON a
|
|
||||||
=> String
|
|
||||||
-> Value
|
|
||||||
-> Maybe a
|
|
||||||
getField field (Object hashmap) = do
|
|
||||||
result <- H.lookup (T.pack field) hashmap
|
|
||||||
case fromJSON result of
|
|
||||||
Success x -> return x
|
|
||||||
_ -> fail "Could not convert from JSON"
|
|
||||||
getField _ _ = fail "Not a JSON object"
|
|
||||||
|
|
||||||
setField :: ToJSON a
|
-- | Retrieve a field value from a template context.
|
||||||
=> String
|
getField :: FromContext a b => String -> Context a -> Maybe b
|
||||||
-> a
|
getField field (Context m) = M.lookup (T.pack field) m >>= fromVal
|
||||||
-> Value
|
|
||||||
-> Value
|
-- | Set a field of a template context. If the field already has a value,
|
||||||
-- | Set a field of a JSON object. If the field already has a value,
|
|
||||||
-- convert it into a list with the new value appended to the old value(s).
|
-- convert it into a list with the new value appended to the old value(s).
|
||||||
-- This is a utility function to be used in preparing template contexts.
|
-- This is a utility function to be used in preparing template contexts.
|
||||||
setField field val (Object hashmap) =
|
setField :: ToContext a b => String -> b -> Context a -> Context a
|
||||||
Object $ H.insertWith combine (T.pack field) (toJSON val) hashmap
|
setField field val (Context m) =
|
||||||
where combine newval oldval =
|
Context $ M.insertWith combine (T.pack field) (toVal val) m
|
||||||
case fromJSON oldval of
|
where
|
||||||
Success xs -> toJSON $ xs ++ [newval]
|
combine newval (ListVal xs) = ListVal (xs ++ [newval])
|
||||||
_ -> toJSON [oldval, newval]
|
combine newval x = ListVal [x, newval]
|
||||||
setField _ _ x = x
|
|
||||||
|
|
||||||
resetField :: ToJSON a
|
-- | Reset a field of a template context. If the field already has a
|
||||||
=> String
|
-- value, the new value replaces it.
|
||||||
-> a
|
|
||||||
-> Value
|
|
||||||
-> Value
|
|
||||||
-- | Reset a field of a JSON object. If the field already has a value,
|
|
||||||
-- the new value replaces it.
|
|
||||||
-- This is a utility function to be used in preparing template contexts.
|
-- This is a utility function to be used in preparing template contexts.
|
||||||
resetField field val (Object hashmap) =
|
resetField :: ToContext a b => String -> b -> Context a -> Context a
|
||||||
Object $ H.insert (T.pack field) (toJSON val) hashmap
|
resetField field val (Context m) =
|
||||||
resetField _ _ x = x
|
Context (M.insert (T.pack field) (toVal val) m)
|
||||||
|
|
||||||
defField :: ToJSON a
|
-- | Set a field of a template context if it currently has no value.
|
||||||
=> String
|
|
||||||
-> a
|
|
||||||
-> Value
|
|
||||||
-> Value
|
|
||||||
-- | Set a field of a JSON object if it currently has no value.
|
|
||||||
-- If it has a value, do nothing.
|
-- If it has a value, do nothing.
|
||||||
-- This is a utility function to be used in preparing template contexts.
|
-- This is a utility function to be used in preparing template contexts.
|
||||||
defField field val (Object hashmap) =
|
defField :: ToContext a b => String -> b -> Context a -> Context a
|
||||||
Object $ H.insertWith f (T.pack field) (toJSON val) hashmap
|
defField field val (Context m) =
|
||||||
where f _newval oldval = oldval
|
Context (M.insertWith f (T.pack field) (toVal val) m)
|
||||||
defField _ _ x = x
|
where
|
||||||
|
f _newval oldval = oldval
|
||||||
|
|
||||||
-- Produce an HTML tag with the given pandoc attributes.
|
-- Produce an HTML tag with the given pandoc attributes.
|
||||||
tagWithAttrs :: String -> Attr -> Doc
|
tagWithAttrs :: HasChars a => String -> Attr -> Doc a
|
||||||
tagWithAttrs tag (ident,classes,kvs) = hsep
|
tagWithAttrs tag (ident,classes,kvs) = hsep
|
||||||
["<" <> text tag
|
["<" <> text tag
|
||||||
,if null ident
|
,if null ident
|
||||||
|
@ -236,15 +206,15 @@ unsmartify opts ('\8216':xs) = '\'' : unsmartify opts xs
|
||||||
unsmartify opts (x:xs) = x : unsmartify opts xs
|
unsmartify opts (x:xs) = x : unsmartify opts xs
|
||||||
unsmartify _ [] = []
|
unsmartify _ [] = []
|
||||||
|
|
||||||
gridTable :: Monad m
|
gridTable :: (Monad m, HasChars a)
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> (WriterOptions -> [Block] -> m Doc)
|
-> (WriterOptions -> [Block] -> m (Doc a))
|
||||||
-> Bool -- ^ headless
|
-> Bool -- ^ headless
|
||||||
-> [Alignment]
|
-> [Alignment]
|
||||||
-> [Double]
|
-> [Double]
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> [[[Block]]]
|
-> [[[Block]]]
|
||||||
-> m Doc
|
-> m (Doc a)
|
||||||
gridTable opts blocksToDoc headless aligns widths headers rows = do
|
gridTable opts blocksToDoc headless aligns widths headers rows = do
|
||||||
-- the number of columns will be used in case of even widths
|
-- the number of columns will be used in case of even widths
|
||||||
let numcols = maximum (length aligns : length widths :
|
let numcols = maximum (length aligns : length widths :
|
||||||
|
@ -299,10 +269,9 @@ gridTable opts blocksToDoc headless aligns widths headers rows = do
|
||||||
| otherwise = handleGivenWidths widths
|
| otherwise = handleGivenWidths widths
|
||||||
(widthsInChars, rawHeaders, rawRows) <- handleWidths
|
(widthsInChars, rawHeaders, rawRows) <- handleWidths
|
||||||
let hpipeBlocks blocks = hcat [beg, middle, end]
|
let hpipeBlocks blocks = hcat [beg, middle, end]
|
||||||
where h = maximum (1 : map height blocks)
|
where sep' = vfill " | "
|
||||||
sep' = lblock 3 $ vcat (replicate h (text " | "))
|
beg = vfill "| "
|
||||||
beg = lblock 2 $ vcat (replicate h (text "| "))
|
end = vfill " |"
|
||||||
end = lblock 2 $ vcat (replicate h (text " |"))
|
|
||||||
middle = chomp $ hcat $ intersperse sep' blocks
|
middle = chomp $ hcat $ intersperse sep' blocks
|
||||||
let makeRow = hpipeBlocks . zipWith lblock widthsInChars
|
let makeRow = hpipeBlocks . zipWith lblock widthsInChars
|
||||||
let head' = makeRow rawHeaders
|
let head' = makeRow rawHeaders
|
||||||
|
@ -427,3 +396,9 @@ elementToListItem opts (Sec lev _nums (ident,_,_) headerText subsecs)
|
||||||
else [Link nullAttr headerText' ('#':ident, "")]
|
else [Link nullAttr headerText' ('#':ident, "")]
|
||||||
listContents = map (elementToListItem opts) subsecs
|
listContents = map (elementToListItem opts) subsecs
|
||||||
elementToListItem _ (Blk _) = []
|
elementToListItem _ (Blk _) = []
|
||||||
|
|
||||||
|
endsWithPlain :: [Block] -> Bool
|
||||||
|
endsWithPlain xs =
|
||||||
|
case lastMay xs of
|
||||||
|
Just (Plain{}) -> True
|
||||||
|
_ -> False
|
||||||
|
|
|
@ -23,7 +23,7 @@ import Text.Pandoc.Highlighting (languages, languagesByExtension)
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -36,31 +36,28 @@ writeTEI opts (Pandoc meta blocks) = do
|
||||||
colwidth = if writerWrapText opts == WrapAuto
|
colwidth = if writerWrapText opts == WrapAuto
|
||||||
then Just $ writerColumns opts
|
then Just $ writerColumns opts
|
||||||
else Nothing
|
else Nothing
|
||||||
render' :: Doc -> Text
|
|
||||||
render' = render colwidth
|
|
||||||
startLvl = case writerTopLevelDivision opts of
|
startLvl = case writerTopLevelDivision opts of
|
||||||
TopLevelPart -> -1
|
TopLevelPart -> -1
|
||||||
TopLevelChapter -> 0
|
TopLevelChapter -> 0
|
||||||
TopLevelSection -> 1
|
TopLevelSection -> 1
|
||||||
TopLevelDefault -> 1
|
TopLevelDefault -> 1
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap (render' . vcat) .
|
(fmap vcat .
|
||||||
mapM (elementToTEI opts startLvl) . hierarchicalize)
|
mapM (elementToTEI opts startLvl) . hierarchicalize)
|
||||||
(fmap render' . inlinesToTEI opts)
|
(fmap chomp . inlinesToTEI opts)
|
||||||
meta
|
meta
|
||||||
main <- (render' . vcat) <$> mapM (elementToTEI opts startLvl) elements
|
main <- vcat <$> mapM (elementToTEI opts startLvl) elements
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$
|
$ defField "mathml" (case writerHTMLMathMethod opts of
|
||||||
defField "mathml" (case writerHTMLMathMethod opts of
|
|
||||||
MathML -> True
|
MathML -> True
|
||||||
_ -> False) metadata
|
_ -> False) metadata
|
||||||
return $
|
return $ render colwidth $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
||||||
-- | Convert an Element to TEI.
|
-- | Convert an Element to TEI.
|
||||||
elementToTEI :: PandocMonad m => WriterOptions -> Int -> Element -> m Doc
|
elementToTEI :: PandocMonad m => WriterOptions -> Int -> Element -> m (Doc Text)
|
||||||
elementToTEI opts _ (Blk block) = blockToTEI opts block
|
elementToTEI opts _ (Blk block) = blockToTEI opts block
|
||||||
elementToTEI opts lvl (Sec _ _num attr title elements) = do
|
elementToTEI opts lvl (Sec _ _num attr title elements) = do
|
||||||
-- TEI doesn't allow sections with no content, so insert some if needed
|
-- TEI doesn't allow sections with no content, so insert some if needed
|
||||||
|
@ -79,7 +76,7 @@ elementToTEI opts lvl (Sec _ _num attr title elements) = do
|
||||||
inTagsSimple "head" titleContents $$ contents
|
inTagsSimple "head" titleContents $$ contents
|
||||||
|
|
||||||
-- | Convert a list of Pandoc blocks to TEI.
|
-- | Convert a list of Pandoc blocks to TEI.
|
||||||
blocksToTEI :: PandocMonad m => WriterOptions -> [Block] -> m Doc
|
blocksToTEI :: PandocMonad m => WriterOptions -> [Block] -> m (Doc Text)
|
||||||
blocksToTEI opts bs = vcat <$> mapM (blockToTEI opts) bs
|
blocksToTEI opts bs = vcat <$> mapM (blockToTEI opts) bs
|
||||||
|
|
||||||
-- | Auxiliary function to convert Plain block to Para.
|
-- | Auxiliary function to convert Plain block to Para.
|
||||||
|
@ -90,13 +87,13 @@ plainToPara x = x
|
||||||
-- | Convert a list of pairs of terms and definitions into a TEI
|
-- | Convert a list of pairs of terms and definitions into a TEI
|
||||||
-- list with labels and items.
|
-- list with labels and items.
|
||||||
deflistItemsToTEI :: PandocMonad m
|
deflistItemsToTEI :: PandocMonad m
|
||||||
=> WriterOptions -> [([Inline],[[Block]])] -> m Doc
|
=> WriterOptions -> [([Inline],[[Block]])] -> m (Doc Text)
|
||||||
deflistItemsToTEI opts items =
|
deflistItemsToTEI opts items =
|
||||||
vcat <$> mapM (uncurry (deflistItemToTEI opts)) items
|
vcat <$> mapM (uncurry (deflistItemToTEI opts)) items
|
||||||
|
|
||||||
-- | Convert a term and a list of blocks into a TEI varlistentry.
|
-- | Convert a term and a list of blocks into a TEI varlistentry.
|
||||||
deflistItemToTEI :: PandocMonad m
|
deflistItemToTEI :: PandocMonad m
|
||||||
=> WriterOptions -> [Inline] -> [[Block]] -> m Doc
|
=> WriterOptions -> [Inline] -> [[Block]] -> m (Doc Text)
|
||||||
deflistItemToTEI opts term defs = do
|
deflistItemToTEI opts term defs = do
|
||||||
term' <- inlinesToTEI opts term
|
term' <- inlinesToTEI opts term
|
||||||
defs' <- blocksToTEI opts $ concatMap (map plainToPara) defs
|
defs' <- blocksToTEI opts $ concatMap (map plainToPara) defs
|
||||||
|
@ -104,15 +101,15 @@ deflistItemToTEI opts term defs = do
|
||||||
inTagsIndented "item" defs'
|
inTagsIndented "item" defs'
|
||||||
|
|
||||||
-- | Convert a list of lists of blocks to a list of TEI list items.
|
-- | Convert a list of lists of blocks to a list of TEI list items.
|
||||||
listItemsToTEI :: PandocMonad m => WriterOptions -> [[Block]] -> m Doc
|
listItemsToTEI :: PandocMonad m => WriterOptions -> [[Block]] -> m (Doc Text)
|
||||||
listItemsToTEI opts items = vcat <$> mapM (listItemToTEI opts) items
|
listItemsToTEI opts items = vcat <$> mapM (listItemToTEI opts) items
|
||||||
|
|
||||||
-- | Convert a list of blocks into a TEI list item.
|
-- | Convert a list of blocks into a TEI list item.
|
||||||
listItemToTEI :: PandocMonad m => WriterOptions -> [Block] -> m Doc
|
listItemToTEI :: PandocMonad m => WriterOptions -> [Block] -> m (Doc Text)
|
||||||
listItemToTEI opts item =
|
listItemToTEI opts item =
|
||||||
inTagsIndented "item" <$> blocksToTEI opts (map plainToPara item)
|
inTagsIndented "item" <$> blocksToTEI opts (map plainToPara item)
|
||||||
|
|
||||||
imageToTEI :: PandocMonad m => WriterOptions -> Attr -> String -> m Doc
|
imageToTEI :: PandocMonad m => WriterOptions -> Attr -> String -> m (Doc Text)
|
||||||
imageToTEI opts attr src = return $ selfClosingTag "graphic" $
|
imageToTEI opts attr src = return $ selfClosingTag "graphic" $
|
||||||
("url", src) : idFromAttr opts attr ++ dims
|
("url", src) : idFromAttr opts attr ++ dims
|
||||||
where
|
where
|
||||||
|
@ -122,7 +119,7 @@ imageToTEI opts attr src = return $ selfClosingTag "graphic" $
|
||||||
Nothing -> []
|
Nothing -> []
|
||||||
|
|
||||||
-- | Convert a Pandoc block element to TEI.
|
-- | Convert a Pandoc block element to TEI.
|
||||||
blockToTEI :: PandocMonad m => WriterOptions -> Block -> m Doc
|
blockToTEI :: PandocMonad m => WriterOptions -> Block -> m (Doc Text)
|
||||||
blockToTEI _ Null = return empty
|
blockToTEI _ Null = return empty
|
||||||
-- Add ids to paragraphs in divs with ids - this is needed for
|
-- Add ids to paragraphs in divs with ids - this is needed for
|
||||||
-- pandoc-citeproc to get link anchors in bibliographies:
|
-- pandoc-citeproc to get link anchors in bibliographies:
|
||||||
|
@ -212,14 +209,14 @@ blockToTEI opts (Table _ _ _ headers rows) = do
|
||||||
tableRowToTEI :: PandocMonad m
|
tableRowToTEI :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> m Doc
|
-> m (Doc Text)
|
||||||
tableRowToTEI opts cols =
|
tableRowToTEI opts cols =
|
||||||
(inTagsIndented "row" . vcat) <$> mapM (tableItemToTEI opts) cols
|
(inTagsIndented "row" . vcat) <$> mapM (tableItemToTEI opts) cols
|
||||||
|
|
||||||
tableHeadersToTEI :: PandocMonad m
|
tableHeadersToTEI :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> m Doc
|
-> m (Doc Text)
|
||||||
tableHeadersToTEI opts cols =
|
tableHeadersToTEI opts cols =
|
||||||
(inTags True "row" [("role","label")] . vcat) <$>
|
(inTags True "row" [("role","label")] . vcat) <$>
|
||||||
mapM (tableItemToTEI opts) cols
|
mapM (tableItemToTEI opts) cols
|
||||||
|
@ -227,16 +224,16 @@ tableHeadersToTEI opts cols =
|
||||||
tableItemToTEI :: PandocMonad m
|
tableItemToTEI :: PandocMonad m
|
||||||
=> WriterOptions
|
=> WriterOptions
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> m Doc
|
-> m (Doc Text)
|
||||||
tableItemToTEI opts item =
|
tableItemToTEI opts item =
|
||||||
(inTags False "cell" [] . vcat) <$> mapM (blockToTEI opts) item
|
(inTags False "cell" [] . vcat) <$> mapM (blockToTEI opts) item
|
||||||
|
|
||||||
-- | Convert a list of inline elements to TEI.
|
-- | Convert a list of inline elements to TEI.
|
||||||
inlinesToTEI :: PandocMonad m => WriterOptions -> [Inline] -> m Doc
|
inlinesToTEI :: PandocMonad m => WriterOptions -> [Inline] -> m (Doc Text)
|
||||||
inlinesToTEI opts lst = hcat <$> mapM (inlineToTEI opts) lst
|
inlinesToTEI opts lst = hcat <$> mapM (inlineToTEI opts) lst
|
||||||
|
|
||||||
-- | Convert an inline element to TEI.
|
-- | Convert an inline element to TEI.
|
||||||
inlineToTEI :: PandocMonad m => WriterOptions -> Inline -> m Doc
|
inlineToTEI :: PandocMonad m => WriterOptions -> Inline -> m (Doc Text)
|
||||||
inlineToTEI _ (Str str) = return $ text $ escapeStringForXML str
|
inlineToTEI _ (Str str) = return $ text $ escapeStringForXML str
|
||||||
inlineToTEI opts (Emph lst) =
|
inlineToTEI opts (Emph lst) =
|
||||||
inTags False "hi" [("rendition","simple:italic")] <$> inlinesToTEI opts lst
|
inTags False "hi" [("rendition","simple:italic")] <$> inlinesToTEI opts lst
|
||||||
|
|
|
@ -21,6 +21,7 @@ import Data.List (maximumBy, transpose)
|
||||||
import Data.Ord (comparing)
|
import Data.Ord (comparing)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
import Network.URI (unEscapeString)
|
import Network.URI (unEscapeString)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import Text.Pandoc.Class (PandocMonad, report)
|
import Text.Pandoc.Class (PandocMonad, report)
|
||||||
|
@ -29,7 +30,7 @@ import Text.Pandoc.Error
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -68,21 +69,17 @@ pandocToTexinfo options (Pandoc meta blocks) = do
|
||||||
let colwidth = if writerWrapText options == WrapAuto
|
let colwidth = if writerWrapText options == WrapAuto
|
||||||
then Just $ writerColumns options
|
then Just $ writerColumns options
|
||||||
else Nothing
|
else Nothing
|
||||||
let render' :: Doc -> Text
|
metadata <- metaToContext options
|
||||||
render' = render colwidth
|
(blockListToTexinfo)
|
||||||
metadata <- metaToJSON options
|
(fmap chomp .inlineListToTexinfo)
|
||||||
(fmap render' . blockListToTexinfo)
|
|
||||||
(fmap render' . inlineListToTexinfo)
|
|
||||||
meta
|
meta
|
||||||
main <- blockListToTexinfo blocks
|
body <- blockListToTexinfo blocks
|
||||||
st <- get
|
st <- get
|
||||||
let body = render colwidth main
|
|
||||||
let context = defField "body" body
|
let context = defField "body" body
|
||||||
$ defField "toc" (writerTableOfContents options)
|
$ defField "toc" (writerTableOfContents options)
|
||||||
$ defField "titlepage" titlePage
|
$ defField "titlepage" titlePage
|
||||||
$
|
$ defField "strikeout" (stStrikeout st) metadata
|
||||||
defField "strikeout" (stStrikeout st) metadata
|
return $ render colwidth $
|
||||||
return $
|
|
||||||
case writerTemplate options of
|
case writerTemplate options of
|
||||||
Nothing -> body
|
Nothing -> body
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
@ -100,7 +97,7 @@ stringToTexinfo = escapeStringUsing texinfoEscapes
|
||||||
, ('\x2019', "'")
|
, ('\x2019', "'")
|
||||||
]
|
]
|
||||||
|
|
||||||
escapeCommas :: PandocMonad m => TI m Doc -> TI m Doc
|
escapeCommas :: PandocMonad m => TI m (Doc Text) -> TI m (Doc Text)
|
||||||
escapeCommas parser = do
|
escapeCommas parser = do
|
||||||
oldEscapeComma <- gets stEscapeComma
|
oldEscapeComma <- gets stEscapeComma
|
||||||
modify $ \st -> st{ stEscapeComma = True }
|
modify $ \st -> st{ stEscapeComma = True }
|
||||||
|
@ -109,13 +106,13 @@ escapeCommas parser = do
|
||||||
return res
|
return res
|
||||||
|
|
||||||
-- | Puts contents into Texinfo command.
|
-- | Puts contents into Texinfo command.
|
||||||
inCmd :: String -> Doc -> Doc
|
inCmd :: String -> Doc Text -> Doc Text
|
||||||
inCmd cmd contents = char '@' <> text cmd <> braces contents
|
inCmd cmd contents = char '@' <> text cmd <> braces contents
|
||||||
|
|
||||||
-- | Convert Pandoc block element to Texinfo.
|
-- | Convert Pandoc block element to Texinfo.
|
||||||
blockToTexinfo :: PandocMonad m
|
blockToTexinfo :: PandocMonad m
|
||||||
=> Block -- ^ Block to convert
|
=> Block -- ^ Block to convert
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
|
|
||||||
blockToTexinfo Null = return empty
|
blockToTexinfo Null = return empty
|
||||||
|
|
||||||
|
@ -241,7 +238,7 @@ blockToTexinfo (Table caption aligns widths heads rows) = do
|
||||||
colDescriptors <-
|
colDescriptors <-
|
||||||
if all (== 0) widths
|
if all (== 0) widths
|
||||||
then do -- use longest entry instead of column widths
|
then do -- use longest entry instead of column widths
|
||||||
cols <- mapM (mapM (liftM (render Nothing . hcat) . mapM blockToTexinfo)) $
|
cols <- mapM (mapM (liftM (T.unpack . render Nothing . hcat) . mapM blockToTexinfo)) $
|
||||||
transpose $ heads : rows
|
transpose $ heads : rows
|
||||||
return $ concatMap ((\x -> "{"++x++"} ") . maximumBy (comparing length)) cols
|
return $ concatMap ((\x -> "{"++x++"} ") . maximumBy (comparing length)) cols
|
||||||
else return $ "@columnfractions " ++ concatMap (printf "%.2f ") widths
|
else return $ "@columnfractions " ++ concatMap (printf "%.2f ") widths
|
||||||
|
@ -259,20 +256,20 @@ blockToTexinfo (Table caption aligns widths heads rows) = do
|
||||||
tableHeadToTexinfo :: PandocMonad m
|
tableHeadToTexinfo :: PandocMonad m
|
||||||
=> [Alignment]
|
=> [Alignment]
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
tableHeadToTexinfo = tableAnyRowToTexinfo "@headitem "
|
tableHeadToTexinfo = tableAnyRowToTexinfo "@headitem "
|
||||||
|
|
||||||
tableRowToTexinfo :: PandocMonad m
|
tableRowToTexinfo :: PandocMonad m
|
||||||
=> [Alignment]
|
=> [Alignment]
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
tableRowToTexinfo = tableAnyRowToTexinfo "@item "
|
tableRowToTexinfo = tableAnyRowToTexinfo "@item "
|
||||||
|
|
||||||
tableAnyRowToTexinfo :: PandocMonad m
|
tableAnyRowToTexinfo :: PandocMonad m
|
||||||
=> String
|
=> String
|
||||||
-> [Alignment]
|
-> [Alignment]
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
tableAnyRowToTexinfo itemtype aligns cols =
|
tableAnyRowToTexinfo itemtype aligns cols =
|
||||||
zipWithM alignedBlock aligns cols >>=
|
zipWithM alignedBlock aligns cols >>=
|
||||||
return . (text itemtype $$) . foldl (\row item -> row $$
|
return . (text itemtype $$) . foldl (\row item -> row $$
|
||||||
|
@ -281,7 +278,7 @@ tableAnyRowToTexinfo itemtype aligns cols =
|
||||||
alignedBlock :: PandocMonad m
|
alignedBlock :: PandocMonad m
|
||||||
=> Alignment
|
=> Alignment
|
||||||
-> [Block]
|
-> [Block]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
-- XXX @flushleft and @flushright text won't get word wrapped. Since word
|
-- XXX @flushleft and @flushright text won't get word wrapped. Since word
|
||||||
-- wrapping is more important than alignment, we ignore the alignment.
|
-- wrapping is more important than alignment, we ignore the alignment.
|
||||||
alignedBlock _ = blockListToTexinfo
|
alignedBlock _ = blockListToTexinfo
|
||||||
|
@ -298,7 +295,7 @@ alignedBlock _ col = blockListToTexinfo col
|
||||||
-- | Convert Pandoc block elements to Texinfo.
|
-- | Convert Pandoc block elements to Texinfo.
|
||||||
blockListToTexinfo :: PandocMonad m
|
blockListToTexinfo :: PandocMonad m
|
||||||
=> [Block]
|
=> [Block]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
blockListToTexinfo [] = return empty
|
blockListToTexinfo [] = return empty
|
||||||
blockListToTexinfo (x:xs) = do
|
blockListToTexinfo (x:xs) = do
|
||||||
x' <- blockToTexinfo x
|
x' <- blockToTexinfo x
|
||||||
|
@ -340,7 +337,7 @@ collectNodes level (x:xs) =
|
||||||
|
|
||||||
makeMenuLine :: PandocMonad m
|
makeMenuLine :: PandocMonad m
|
||||||
=> Block
|
=> Block
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
makeMenuLine (Header _ _ lst) = do
|
makeMenuLine (Header _ _ lst) = do
|
||||||
txt <- inlineListForNode lst
|
txt <- inlineListForNode lst
|
||||||
return $ text "* " <> txt <> text "::"
|
return $ text "* " <> txt <> text "::"
|
||||||
|
@ -348,7 +345,7 @@ makeMenuLine _ = throwError $ PandocSomeError "makeMenuLine called with non-Head
|
||||||
|
|
||||||
listItemToTexinfo :: PandocMonad m
|
listItemToTexinfo :: PandocMonad m
|
||||||
=> [Block]
|
=> [Block]
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
listItemToTexinfo lst = do
|
listItemToTexinfo lst = do
|
||||||
contents <- blockListToTexinfo lst
|
contents <- blockListToTexinfo lst
|
||||||
let spacer = case reverse lst of
|
let spacer = case reverse lst of
|
||||||
|
@ -358,7 +355,7 @@ listItemToTexinfo lst = do
|
||||||
|
|
||||||
defListItemToTexinfo :: PandocMonad m
|
defListItemToTexinfo :: PandocMonad m
|
||||||
=> ([Inline], [[Block]])
|
=> ([Inline], [[Block]])
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
defListItemToTexinfo (term, defs) = do
|
defListItemToTexinfo (term, defs) = do
|
||||||
term' <- inlineListToTexinfo term
|
term' <- inlineListToTexinfo term
|
||||||
let defToTexinfo bs = do d <- blockListToTexinfo bs
|
let defToTexinfo bs = do d <- blockListToTexinfo bs
|
||||||
|
@ -371,13 +368,13 @@ defListItemToTexinfo (term, defs) = do
|
||||||
-- | Convert list of inline elements to Texinfo.
|
-- | Convert list of inline elements to Texinfo.
|
||||||
inlineListToTexinfo :: PandocMonad m
|
inlineListToTexinfo :: PandocMonad m
|
||||||
=> [Inline] -- ^ Inlines to convert
|
=> [Inline] -- ^ Inlines to convert
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
inlineListToTexinfo lst = hcat <$> mapM inlineToTexinfo lst
|
inlineListToTexinfo lst = hcat <$> mapM inlineToTexinfo lst
|
||||||
|
|
||||||
-- | Convert list of inline elements to Texinfo acceptable for a node name.
|
-- | Convert list of inline elements to Texinfo acceptable for a node name.
|
||||||
inlineListForNode :: PandocMonad m
|
inlineListForNode :: PandocMonad m
|
||||||
=> [Inline] -- ^ Inlines to convert
|
=> [Inline] -- ^ Inlines to convert
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
inlineListForNode = return . text . stringToTexinfo .
|
inlineListForNode = return . text . stringToTexinfo .
|
||||||
filter (not . disallowedInNode) . stringify
|
filter (not . disallowedInNode) . stringify
|
||||||
|
|
||||||
|
@ -388,7 +385,7 @@ disallowedInNode c = c `elem` (".,:()" :: String)
|
||||||
-- | Convert inline element to Texinfo
|
-- | Convert inline element to Texinfo
|
||||||
inlineToTexinfo :: PandocMonad m
|
inlineToTexinfo :: PandocMonad m
|
||||||
=> Inline -- ^ Inline to convert
|
=> Inline -- ^ Inline to convert
|
||||||
-> TI m Doc
|
-> TI m (Doc Text)
|
||||||
|
|
||||||
inlineToTexinfo (Span _ lst) =
|
inlineToTexinfo (Span _ lst) =
|
||||||
inlineListToTexinfo lst
|
inlineListToTexinfo lst
|
||||||
|
|
|
@ -23,7 +23,7 @@ import Text.Pandoc.Definition
|
||||||
import Text.Pandoc.ImageSize
|
import Text.Pandoc.ImageSize
|
||||||
import Text.Pandoc.Logging
|
import Text.Pandoc.Logging
|
||||||
import Text.Pandoc.Options
|
import Text.Pandoc.Options
|
||||||
import Text.Pandoc.Pretty (render)
|
import Text.DocLayout (render)
|
||||||
import Text.Pandoc.Shared
|
import Text.Pandoc.Shared
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared
|
import Text.Pandoc.Writers.Shared
|
||||||
|
@ -51,13 +51,13 @@ writeTextile opts document =
|
||||||
pandocToTextile :: PandocMonad m
|
pandocToTextile :: PandocMonad m
|
||||||
=> WriterOptions -> Pandoc -> TW m Text
|
=> WriterOptions -> Pandoc -> TW m Text
|
||||||
pandocToTextile opts (Pandoc meta blocks) = do
|
pandocToTextile opts (Pandoc meta blocks) = do
|
||||||
metadata <- metaToJSON opts (blockListToTextile opts)
|
metadata <- metaToContext opts (blockListToTextile opts)
|
||||||
(inlineListToTextile opts) meta
|
(inlineListToTextile opts) meta
|
||||||
body <- blockListToTextile opts blocks
|
body <- blockListToTextile opts blocks
|
||||||
notes <- gets $ unlines . reverse . stNotes
|
notes <- gets $ unlines . reverse . stNotes
|
||||||
let main = pack $ body ++ if null notes then "" else "\n\n" ++ notes
|
let main = body ++ if null notes then "" else "\n\n" ++ notes
|
||||||
let context = defField "body" main metadata
|
let context = defField "body" main metadata
|
||||||
return $
|
return $ pack $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
|
|
|
@ -30,7 +30,7 @@ import Text.Pandoc.Options (WrapOption (..), WriterOptions (writerTableOfContent
|
||||||
import Text.Pandoc.Shared (escapeURI, isURI, linesToPara, removeFormatting,
|
import Text.Pandoc.Shared (escapeURI, isURI, linesToPara, removeFormatting,
|
||||||
substitute, trimr)
|
substitute, trimr)
|
||||||
import Text.Pandoc.Templates (renderTemplate)
|
import Text.Pandoc.Templates (renderTemplate)
|
||||||
import Text.Pandoc.Writers.Shared (defField, metaToJSON)
|
import Text.Pandoc.Writers.Shared (defField, metaToContext)
|
||||||
|
|
||||||
data WriterState = WriterState {
|
data WriterState = WriterState {
|
||||||
stIndent :: String, -- Indent after the marker at the beginning of list items
|
stIndent :: String, -- Indent after the marker at the beginning of list items
|
||||||
|
@ -50,16 +50,15 @@ writeZimWiki opts document = evalStateT (pandocToZimWiki opts document) def
|
||||||
-- | Return ZimWiki representation of document.
|
-- | Return ZimWiki representation of document.
|
||||||
pandocToZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> ZW m Text
|
pandocToZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> ZW m Text
|
||||||
pandocToZimWiki opts (Pandoc meta blocks) = do
|
pandocToZimWiki opts (Pandoc meta blocks) = do
|
||||||
metadata <- metaToJSON opts
|
metadata <- metaToContext opts
|
||||||
(fmap trimr . blockListToZimWiki opts)
|
(fmap trimr . blockListToZimWiki opts)
|
||||||
(inlineListToZimWiki opts)
|
(fmap trimr . inlineListToZimWiki opts)
|
||||||
meta
|
meta
|
||||||
body <- pack <$> blockListToZimWiki opts blocks
|
main <- blockListToZimWiki opts blocks
|
||||||
--let header = "Content-Type: text/x-zim-wiki\nWiki-Format: zim 0.4\n"
|
--let header = "Content-Type: text/x-zim-wiki\nWiki-Format: zim 0.4\n"
|
||||||
let main = body
|
|
||||||
let context = defField "body" main
|
let context = defField "body" main
|
||||||
$ defField "toc" (writerTableOfContents opts) metadata
|
$ defField "toc" (writerTableOfContents opts) metadata
|
||||||
return $
|
return $ pack $
|
||||||
case writerTemplate opts of
|
case writerTemplate opts of
|
||||||
Just tpl -> renderTemplate tpl context
|
Just tpl -> renderTemplate tpl context
|
||||||
Nothing -> main
|
Nothing -> main
|
||||||
|
|
|
@ -25,8 +25,9 @@ import Data.Char (isAscii, isSpace, ord)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Text.HTML.TagSoup.Entity (lookupEntity, htmlEntities)
|
import Text.HTML.TagSoup.Entity (lookupEntity, htmlEntities)
|
||||||
import Text.Pandoc.Pretty
|
import Text.DocLayout
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
import Data.String
|
||||||
|
|
||||||
-- | Escape one character as needed for XML.
|
-- | Escape one character as needed for XML.
|
||||||
escapeCharForXML :: Char -> String
|
escapeCharForXML :: Char -> String
|
||||||
|
@ -54,14 +55,15 @@ escapeNls (x:xs)
|
||||||
escapeNls [] = []
|
escapeNls [] = []
|
||||||
|
|
||||||
-- | Return a text object with a string of formatted XML attributes.
|
-- | Return a text object with a string of formatted XML attributes.
|
||||||
attributeList :: [(String, String)] -> Doc
|
attributeList :: IsString a => [(String, String)] -> Doc a
|
||||||
attributeList = hcat . map
|
attributeList = hcat . map
|
||||||
(\(a, b) -> text (' ' : escapeStringForXML a ++ "=\"" ++
|
(\(a, b) -> text (' ' : escapeStringForXML a ++ "=\"" ++
|
||||||
escapeNls (escapeStringForXML b) ++ "\""))
|
escapeNls (escapeStringForXML b) ++ "\""))
|
||||||
|
|
||||||
-- | Put the supplied contents between start and end tags of tagType,
|
-- | Put the supplied contents between start and end tags of tagType,
|
||||||
-- with specified attributes and (if specified) indentation.
|
-- with specified attributes and (if specified) indentation.
|
||||||
inTags:: Bool -> String -> [(String, String)] -> Doc -> Doc
|
inTags:: IsString a
|
||||||
|
=> Bool -> String -> [(String, String)] -> Doc a -> Doc a
|
||||||
inTags isIndented tagType attribs contents =
|
inTags isIndented tagType attribs contents =
|
||||||
let openTag = char '<' <> text tagType <> attributeList attribs <>
|
let openTag = char '<' <> text tagType <> attributeList attribs <>
|
||||||
char '>'
|
char '>'
|
||||||
|
@ -71,16 +73,16 @@ inTags isIndented tagType attribs contents =
|
||||||
else openTag <> contents <> closeTag
|
else openTag <> contents <> closeTag
|
||||||
|
|
||||||
-- | Return a self-closing tag of tagType with specified attributes
|
-- | Return a self-closing tag of tagType with specified attributes
|
||||||
selfClosingTag :: String -> [(String, String)] -> Doc
|
selfClosingTag :: IsString a => String -> [(String, String)] -> Doc a
|
||||||
selfClosingTag tagType attribs =
|
selfClosingTag tagType attribs =
|
||||||
char '<' <> text tagType <> attributeList attribs <> text " />"
|
char '<' <> text tagType <> attributeList attribs <> text " />"
|
||||||
|
|
||||||
-- | Put the supplied contents between start and end tags of tagType.
|
-- | Put the supplied contents between start and end tags of tagType.
|
||||||
inTagsSimple :: String -> Doc -> Doc
|
inTagsSimple :: IsString a => String -> Doc a -> Doc a
|
||||||
inTagsSimple tagType = inTags False tagType []
|
inTagsSimple tagType = inTags False tagType []
|
||||||
|
|
||||||
-- | Put the supplied contents in indented block btw start and end tags.
|
-- | Put the supplied contents in indented block btw start and end tags.
|
||||||
inTagsIndented :: String -> Doc -> Doc
|
inTagsIndented :: IsString a => String -> Doc a -> Doc a
|
||||||
inTagsIndented tagType = inTags True tagType []
|
inTagsIndented tagType = inTags True tagType []
|
||||||
|
|
||||||
-- | Escape all non-ascii characters using numerical entities.
|
-- | Escape all non-ascii characters using numerical entities.
|
||||||
|
|
|
@ -22,7 +22,8 @@ extra-deps:
|
||||||
- tasty-lua-0.2.0
|
- tasty-lua-0.2.0
|
||||||
- skylighting-core-0.8.2
|
- skylighting-core-0.8.2
|
||||||
- skylighting-0.8.2
|
- skylighting-0.8.2
|
||||||
- doctemplates-0.3.0.1
|
- doclayout-0.1
|
||||||
|
- doctemplates-0.5
|
||||||
ghc-options:
|
ghc-options:
|
||||||
"$locals": -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Widentities -Wcpp-undef -fhide-source-paths -Wno-missing-home-modules
|
"$locals": -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Widentities -Wcpp-undef -fhide-source-paths -Wno-missing-home-modules
|
||||||
resolver: lts-13.17
|
resolver: lts-13.17
|
||||||
|
|
|
@ -17,5 +17,4 @@ without being broken into pieces.
|
||||||
A paragraph can span multiple lines
|
A paragraph can span multiple lines
|
||||||
without being broken into pieces.
|
without being broken into pieces.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,5 +10,4 @@
|
||||||
</code>
|
</code>
|
||||||
* ok
|
* ok
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -14,5 +14,4 @@
|
||||||
| text
|
| text
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
- bar
|
- bar
|
||||||
* baz
|
* baz
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
% pandoc -f muse -t dokuwiki
|
% pandoc -f muse -t dokuwiki
|
||||||
|
@ -20,6 +19,5 @@
|
||||||
- bar
|
- bar
|
||||||
- baz
|
- baz
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -198,4 +198,3 @@ multiple lines.</td>
|
||||||
the blank line between rows.</td>
|
the blank line between rows.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -44,4 +44,3 @@ Multiline table without column headers:
|
||||||
|
|
||||||
| First |row | 12.0|Example of a row that spans multiple lines. |
|
| 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.|
|
| Second |row | 5.0|Here’s another one. Note the blank line between rows.|
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,3 @@ multiple lines.</td></tr><tr><td align="center">Second</td><td align="left">row<
|
||||||
the blank line between rows.</td></tr></table><p><emphasis /></p><p>Table without column headers:</p><table><tr><th align="right" /><th align="left" /><th align="center" /><th align="right" /></tr><tr><td align="right">12</td><td align="left">12</td><td align="center">12</td><td align="right">12</td></tr><tr><td align="right">123</td><td align="left">123</td><td align="center">123</td><td align="right">123</td></tr><tr><td align="right">1</td><td align="left">1</td><td align="center">1</td><td align="right">1</td></tr></table><p><emphasis /></p><p>Multiline table without column headers:</p><table><tr><th align="center" /><th align="left" /><th align="right" /><th align="left" /></tr><tr><td align="center">First</td><td align="left">row</td><td align="right">12.0</td><td align="left">Example of a row that spans
|
the blank line between rows.</td></tr></table><p><emphasis /></p><p>Table without column headers:</p><table><tr><th align="right" /><th align="left" /><th align="center" /><th align="right" /></tr><tr><td align="right">12</td><td align="left">12</td><td align="center">12</td><td align="right">12</td></tr><tr><td align="right">123</td><td align="left">123</td><td align="center">123</td><td align="right">123</td></tr><tr><td align="right">1</td><td align="left">1</td><td align="center">1</td><td align="right">1</td></tr></table><p><emphasis /></p><p>Multiline table without column headers:</p><table><tr><th align="center" /><th align="left" /><th align="right" /><th align="left" /></tr><tr><td align="center">First</td><td align="left">row</td><td align="right">12.0</td><td align="left">Example of a row that spans
|
||||||
multiple lines.</td></tr><tr><td align="center">Second</td><td align="left">row</td><td align="right">5.0</td><td align="left">Here’s another one. Note
|
multiple lines.</td></tr><tr><td align="center">Second</td><td align="left">row</td><td align="right">5.0</td><td align="left">Here’s another one. Note
|
||||||
the blank line between rows.</td></tr></table><p><emphasis /></p></section></body></FictionBook>
|
the blank line between rows.</td></tr></table><p><emphasis /></p></section></body></FictionBook>
|
||||||
|
|
||||||
|
|
|
@ -41,4 +41,3 @@ Multiline table without column headers:
|
||||||
|
|
||||||
|First|row|12.0|Example of a row that spans multiple lines.|
|
|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.|
|
|Second|row|5.0|Here's another one. Note the blank line between rows.|
|
||||||
|
|
||||||
|
|
|
@ -143,4 +143,3 @@ Multiline table without column headers:
|
||||||
|align="right"| 5.0
|
|align="right"| 5.0
|
||||||
| Here’s another one. Note the blank line between rows.
|
| Here’s another one. Note the blank line between rows.
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
|
|
@ -357,4 +357,3 @@
|
||||||
}
|
}
|
||||||
\intbl\row}
|
\intbl\row}
|
||||||
{\pard \ql \f0 \sa180 \li0 \fi0 \par}
|
{\pard \ql \f0 \sa180 \li0 \fi0 \par}
|
||||||
|
|
||||||
|
|
|
@ -164,4 +164,3 @@ Multiline table without column headers:
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -72,4 +72,3 @@ Multiline table without column headers:
|
||||||
Second row 5.0 Here's another one. Note
|
Second row 5.0 Here's another one. Note
|
||||||
the blank line between rows.
|
the blank line between rows.
|
||||||
---------- --------- ----------- ---------------------------
|
---------- --------- ----------- ---------------------------
|
||||||
|
|
||||||
|
|
|
@ -43,4 +43,3 @@ Multiline table without column headers:
|
||||||
|= |= |= |=
|
|= |= |= |=
|
||||||
|First |row |12.0 |Example of a row that spans multiple lines.
|
|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.
|
|Second |row |5.0 |Here’s another one. Note the blank line between rows.
|
||||||
|
|
||||||
|
|
|
@ -53,4 +53,3 @@ Multiline table without column headers:
|
||||||
|:--------:|:----|-----:|-----------------------------------------------------|
|
|:--------:|:----|-----:|-----------------------------------------------------|
|
||||||
| First |row | 12.0|Example of a row that spans multiple lines. |
|
| 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.|
|
| Second |row | 5.0|Here’s another one. Note the blank line between rows.|
|
||||||
|
|
||||||
|
|
|
@ -780,4 +780,3 @@ as well as [bracketed text]. <a href="#fnref3">↩</a></p></li>
|
||||||
<li id="fn4"><p>In quote. <a href="#fnref4">↩</a></p></li>
|
<li id="fn4"><p>In quote. <a href="#fnref4">↩</a></p></li>
|
||||||
<li id="fn5"><p>In list. <a href="#fnref5">↩</a></p></li>
|
<li id="fn5"><p>In list. <a href="#fnref5">↩</a></p></li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
|
2598
test/writer.docbook4
2598
test/writer.docbook4
File diff suppressed because it is too large
Load diff
2521
test/writer.docbook5
2521
test/writer.docbook5
File diff suppressed because it is too large
Load diff
|
@ -619,7 +619,6 @@ LaTeX
|
||||||
- Here’s some display math:
|
- Here’s some display math:
|
||||||
|
|
||||||
.. math:: \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}
|
.. math:: \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}
|
||||||
|
|
||||||
- Here’s one that has a line break in it: :math:`\alpha + \omega \times x^2`.
|
- Here’s one that has a line break in it: :math:`\alpha + \omega \times x^2`.
|
||||||
|
|
||||||
These shouldn’t be math:
|
These shouldn’t be math:
|
||||||
|
|
|
@ -717,3 +717,4 @@ fn4. In quote.
|
||||||
|
|
||||||
|
|
||||||
fn5. In list.
|
fn5. In list.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue