Split writeDocbook into writeDocbook4, writeDocbook5.

Removed writerDocbookVersion in WriterOptions.
Renamed default.docbook template to default.docbook4.
Allow docbook4 as an output format.
But alias docbook = docbook4.
This commit is contained in:
John MacFarlane 2017-01-26 22:40:57 +01:00
parent 190943e1fd
commit b6c1d491f5
11 changed files with 64 additions and 46 deletions

View file

@ -278,9 +278,9 @@ General options
`man` (groff man), `mediawiki` (MediaWiki markup), `man` (groff man), `mediawiki` (MediaWiki markup),
`dokuwiki` (DokuWiki markup), `zimwiki` (ZimWiki markup), `dokuwiki` (DokuWiki markup), `zimwiki` (ZimWiki markup),
`textile` (Textile), `org` (Emacs Org mode), `textile` (Textile), `org` (Emacs Org mode),
`texinfo` (GNU Texinfo), `opml` (OPML), `docbook` (DocBook 4), `texinfo` (GNU Texinfo), `opml` (OPML), `docbook` or `docbook4`
`docbook5` (DocBook 5), `opendocument` (OpenDocument), `odt` (DocBook 4), `docbook5` (DocBook 5), `opendocument` (OpenDocument),
(OpenOffice text document), `docx` (Word docx), `haddock` `odt` (OpenOffice text document), `docx` (Word docx), `haddock`
(Haddock markup), `rtf` (rich text format), `epub` or `epub2` (EPUB v2 (Haddock markup), `rtf` (rich text format), `epub` or `epub2` (EPUB v2
book), `epub3` (EPUB v3), `fb2` (FictionBook2 e-book), book), `epub3` (EPUB v3), `fb2` (FictionBook2 e-book),
`asciidoc` (AsciiDoc), `icml` (InDesign ICML), `tei` (TEI `asciidoc` (AsciiDoc), `icml` (InDesign ICML), `tei` (TEI
@ -569,7 +569,7 @@ General writer options
: Include an automatically generated table of contents (or, in : Include an automatically generated table of contents (or, in
the case of `latex`, `context`, `docx`, and `rst`, an instruction to create the case of `latex`, `context`, `docx`, and `rst`, an instruction to create
one) in the output document. This option has no effect on `man`, one) in the output document. This option has no effect on `man`,
`docbook`, `docbook5`, `slidy`, `slideous`, `s5`, or `odt` output. `docbook4`, `docbook5`, `slidy`, `slideous`, `s5`, or `odt` output.
`--toc-depth=`*NUMBER* `--toc-depth=`*NUMBER*
@ -947,7 +947,7 @@ Math rendering in HTML
`--mathml`[`=`*URL*] `--mathml`[`=`*URL*]
: Convert TeX math to [MathML] (in `docbook`, `docbook5`, : Convert TeX math to [MathML] (in `docbook4`, `docbook5`,
`html4` and `html5`). In standalone HTML output, a small `html4` and `html5`). In standalone HTML output, a small
JavaScript (or a link to such a script if a *URL* is JavaScript (or a link to such a script if a *URL* is
supplied) will be inserted that allows the MathML to be supplied) will be inserted that allows the MathML to be

@ -1 +1 @@
Subproject commit 335360e40c5cd395b33954906144c834783b41fd Subproject commit c4ba8bab6248f8999e520547f1c45f10de85db9d

View file

@ -38,7 +38,7 @@ Data-Files:
-- templates -- templates
data/templates/default.html4 data/templates/default.html4
data/templates/default.html5 data/templates/default.html5
data/templates/default.docbook data/templates/default.docbook4
data/templates/default.docbook5 data/templates/default.docbook5
data/templates/default.tei data/templates/default.tei
data/templates/default.beamer data/templates/default.beamer
@ -145,7 +145,7 @@ Extra-Source-Files:
tests/s5-fragment.html tests/s5-fragment.html
tests/s5-inserts.html tests/s5-inserts.html
tests/tables.context tests/tables.context
tests/tables.docbook tests/tables.docbook4
tests/tables.docbook5 tests/tables.docbook5
tests/tables.dokuwiki tests/tables.dokuwiki
tests/tables.zimwiki tests/tables.zimwiki
@ -171,7 +171,7 @@ Extra-Source-Files:
tests/testsuite.txt tests/testsuite.txt
tests/writer.latex tests/writer.latex
tests/writer.context tests/writer.context
tests/writer.docbook tests/writer.docbook4
tests/writer.docbook5 tests/writer.docbook5
tests/writer.html4 tests/writer.html4
tests/writer.html5 tests/writer.html5

View file

@ -104,7 +104,8 @@ module Text.Pandoc
, writeHtml5 , writeHtml5
, writeHtml5String , writeHtml5String
, writeICML , writeICML
, writeDocbook , writeDocbook4
, writeDocbook5
, writeOPML , writeOPML
, writeOpenDocument , writeOpenDocument
, writeMan , writeMan
@ -298,9 +299,9 @@ writers = [
writeHtml5String o{ writerSlideVariant = DZSlides }) writeHtml5String o{ writerSlideVariant = DZSlides })
,("revealjs" , StringWriter $ \o -> ,("revealjs" , StringWriter $ \o ->
writeHtml5String o{ writerSlideVariant = RevealJsSlides }) writeHtml5String o{ writerSlideVariant = RevealJsSlides })
,("docbook" , StringWriter writeDocbook) ,("docbook" , StringWriter writeDocbook5)
,("docbook5" , StringWriter $ \o -> ,("docbook4" , StringWriter writeDocbook4)
writeDocbook o{ writerDocbook5 = True }) ,("docbook5" , StringWriter writeDocbook5)
,("opml" , StringWriter writeOPML) ,("opml" , StringWriter writeOPML)
,("opendocument" , StringWriter writeOpenDocument) ,("opendocument" , StringWriter writeOpenDocument)
,("latex" , StringWriter writeLaTeX) ,("latex" , StringWriter writeLaTeX)

View file

@ -167,7 +167,6 @@ data WriterOptions = WriterOptions
, writerSourceURL :: Maybe String -- ^ Absolute URL + directory of 1st source file , writerSourceURL :: Maybe String -- ^ Absolute URL + directory of 1st source file
, writerUserDataDir :: Maybe FilePath -- ^ Path of user data directory , writerUserDataDir :: Maybe FilePath -- ^ Path of user data directory
, writerCiteMethod :: CiteMethod -- ^ How to print cites , writerCiteMethod :: CiteMethod -- ^ How to print cites
, writerDocbook5 :: Bool -- ^ Produce DocBook5
, writerHtmlQTags :: Bool -- ^ Use @<q>@ tags for quotes in HTML , writerHtmlQTags :: Bool -- ^ Use @<q>@ tags for quotes in HTML
, writerBeamer :: Bool -- ^ Produce beamer LaTeX slide show , writerBeamer :: Bool -- ^ Produce beamer LaTeX slide show
, writerSlideLevel :: Maybe Int -- ^ Force header level of slides , writerSlideLevel :: Maybe Int -- ^ Force header level of slides
@ -208,7 +207,6 @@ instance Default WriterOptions where
, writerSourceURL = Nothing , writerSourceURL = Nothing
, writerUserDataDir = Nothing , writerUserDataDir = Nothing
, writerCiteMethod = Citeproc , writerCiteMethod = Citeproc
, writerDocbook5 = False
, writerHtmlQTags = False , writerHtmlQTags = False
, writerBeamer = False , writerBeamer = False
, writerSlideLevel = Nothing , writerSlideLevel = Nothing

View file

@ -55,13 +55,14 @@ getDefaultTemplate :: (Maybe FilePath) -- ^ User data directory to search first
getDefaultTemplate user writer = do getDefaultTemplate user writer = do
let format = takeWhile (`notElem` ("+-" :: String)) writer -- strip off extensions let format = takeWhile (`notElem` ("+-" :: String)) writer -- strip off extensions
case format of case format of
"native" -> return $ Right "" "native" -> return $ Right ""
"json" -> return $ Right "" "json" -> return $ Right ""
"docx" -> return $ Right "" "docx" -> return $ Right ""
"fb2" -> return $ Right "" "fb2" -> return $ Right ""
"odt" -> getDefaultTemplate user "opendocument" "odt" -> getDefaultTemplate user "opendocument"
"html" -> getDefaultTemplate user "html5" "html" -> getDefaultTemplate user "html5"
"epub" -> getDefaultTemplate user "epub2" "docbook" -> getDefaultTemplate user "docbook5"
"epub" -> getDefaultTemplate user "epub2"
"markdown_strict" -> getDefaultTemplate user "markdown" "markdown_strict" -> getDefaultTemplate user "markdown"
"multimarkdown" -> getDefaultTemplate user "markdown" "multimarkdown" -> getDefaultTemplate user "markdown"
"markdown_github" -> getDefaultTemplate user "markdown" "markdown_github" -> getDefaultTemplate user "markdown"

View file

@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Conversion of 'Pandoc' documents to Docbook XML. Conversion of 'Pandoc' documents to Docbook XML.
-} -}
module Text.Pandoc.Writers.Docbook ( writeDocbook) where module Text.Pandoc.Writers.Docbook ( writeDocbook4, writeDocbook5 ) where
import Text.Pandoc.Definition import Text.Pandoc.Definition
import Text.Pandoc.XML import Text.Pandoc.XML
import Text.Pandoc.Shared import Text.Pandoc.Shared
@ -48,9 +48,15 @@ import Text.TeXMath
import qualified Text.XML.Light as Xml import qualified Text.XML.Light as Xml
import Data.Generics (everywhere, mkT) import Data.Generics (everywhere, mkT)
import Text.Pandoc.Class (PandocMonad) import Text.Pandoc.Class (PandocMonad)
import Control.Monad.Reader
data DocBookVersion = DocBook4 | DocBook5
deriving (Eq, Show)
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] -> 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 <- render Nothing <$> inlinesToDocbook opts name'
let colwidth = if writerWrapText opts == WrapAuto let colwidth = if writerWrapText opts == WrapAuto
@ -73,8 +79,16 @@ authorToDocbook opts name' = do
in inTagsSimple "firstname" (text $ escapeStringForXML firstname) $$ in inTagsSimple "firstname" (text $ escapeStringForXML firstname) $$
inTagsSimple "surname" (text $ escapeStringForXML lastname) inTagsSimple "surname" (text $ escapeStringForXML lastname)
writeDocbook4 :: PandocMonad m => WriterOptions -> Pandoc -> m String
writeDocbook4 opts d =
runReaderT (writeDocbook opts d) DocBook4
writeDocbook5 :: PandocMonad m => WriterOptions -> Pandoc -> m String
writeDocbook5 opts d =
runReaderT (writeDocbook opts d) DocBook5
-- | Convert Pandoc document to string in Docbook format. -- | Convert Pandoc document to string in Docbook format.
writeDocbook :: PandocMonad m => WriterOptions -> Pandoc -> m String writeDocbook :: PandocMonad m => WriterOptions -> Pandoc -> DB m String
writeDocbook opts (Pandoc meta blocks) = do writeDocbook opts (Pandoc meta blocks) = do
let elements = hierarchicalize blocks let elements = hierarchicalize blocks
let colwidth = if writerWrapText opts == WrapAuto let colwidth = if writerWrapText opts == WrapAuto
@ -100,7 +114,7 @@ writeDocbook opts (Pandoc meta blocks) = do
hierarchicalize)) hierarchicalize))
(fmap (render colwidth) . inlinesToDocbook opts') (fmap (render colwidth) . inlinesToDocbook opts')
meta' meta'
main <- (render' . vcat) <$> mapM (elementToDocbook opts' startLvl) elements main <- (render' . 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
@ -111,9 +125,10 @@ writeDocbook opts (Pandoc meta blocks) = do
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 -> m Doc elementToDocbook :: PandocMonad m => WriterOptions -> Int -> Element -> DB m Doc
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
-- Docbook doesn't allow sections with no content, so insert some if needed -- Docbook doesn't allow sections with no content, so insert some if needed
let elements' = if null elements let elements' = if null elements
then [Blk (Para [])] then [Blk (Para [])]
@ -121,15 +136,15 @@ elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) = do
tag = case lvl of tag = case lvl of
-1 -> "part" -1 -> "part"
0 -> "chapter" 0 -> "chapter"
n | n >= 1 && n <= 5 -> if writerDocbook5 opts n | n >= 1 && n <= 5 -> if version == DocBook5
then "section" then "section"
else "sect" ++ show n else "sect" ++ show n
_ -> "simplesect" _ -> "simplesect"
idName = if writerDocbook5 opts idName = if version == DocBook5
then "xml:id" then "xml:id"
else "id" else "id"
idAttr = [(idName, writerIdentifierPrefix opts ++ id') | not (null id')] idAttr = [(idName, writerIdentifierPrefix opts ++ id') | not (null id')]
nsAttr = if writerDocbook5 opts && lvl == 0 then [("xmlns", "http://docbook.org/ns/docbook"),("xmlns:xlink", "http://www.w3.org/1999/xlink")] nsAttr = if version == DocBook5 && lvl == 0 then [("xmlns", "http://docbook.org/ns/docbook"),("xmlns:xlink", "http://www.w3.org/1999/xlink")]
else [] else []
attribs = nsAttr ++ idAttr attribs = nsAttr ++ idAttr
contents <- mapM (elementToDocbook opts (lvl + 1)) elements' contents <- mapM (elementToDocbook opts (lvl + 1)) elements'
@ -138,7 +153,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] -> m Doc blocksToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m Doc
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 +164,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]])] -> m Doc => WriterOptions -> [([Inline],[[Block]])] -> DB m Doc
deflistItemsToDocbook opts items = deflistItemsToDocbook opts items =
vcat <$> mapM (\(term, defs) -> deflistItemToDocbook opts term defs) items vcat <$> mapM (\(term, defs) -> deflistItemToDocbook opts term defs) 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]] -> m Doc => WriterOptions -> [Inline] -> [[Block]] -> DB m Doc
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,11 +179,11 @@ 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]] -> m Doc listItemsToDocbook :: PandocMonad m => WriterOptions -> [[Block]] -> DB m Doc
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] -> m Doc listItemToDocbook :: PandocMonad m => WriterOptions -> [Block] -> DB m Doc
listItemToDocbook opts item = listItemToDocbook opts item =
inTagsIndented "listitem" <$> blocksToDocbook opts (map plainToPara item) inTagsIndented "listitem" <$> blocksToDocbook opts (map plainToPara item)
@ -182,7 +197,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 -> m Doc blockToDocbook :: PandocMonad m => WriterOptions -> Block -> DB m Doc
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:
@ -260,9 +275,11 @@ blockToDocbook opts (OrderedList (start, numstyle, _) (first:rest)) = do
blockToDocbook opts (DefinitionList lst) = do blockToDocbook opts (DefinitionList lst) = do
let attribs = [("spacing", "compact") | isTightList $ concatMap snd lst] let attribs = [("spacing", "compact") | isTightList $ concatMap snd lst]
inTags True "variablelist" attribs <$> deflistItemsToDocbook opts lst inTags True "variablelist" attribs <$> deflistItemsToDocbook opts lst
blockToDocbook opts (RawBlock f str) blockToDocbook _ (RawBlock f str)
| f == "docbook" = return $ text str -- raw XML block | f == "docbook" = return $ text str -- raw XML block
| f == "html" = if writerDocbook5 opts | f == "html" = do
version <- ask
if version == DocBook5
then return empty -- No html in Docbook5 then return empty -- No html in Docbook5
else return $ text str -- allow html for backwards compatibility else return $ text str -- allow html for backwards compatibility
| otherwise = return empty | otherwise = return empty
@ -306,23 +323,23 @@ alignmentToString alignment = case alignment of
tableRowToDocbook :: PandocMonad m tableRowToDocbook :: PandocMonad m
=> WriterOptions => WriterOptions
-> [[Block]] -> [[Block]]
-> m Doc -> DB m Doc
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]
-> m Doc -> DB m Doc
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] -> m Doc inlinesToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> DB m Doc
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 -> m Doc inlineToDocbook :: PandocMonad m => WriterOptions -> Inline -> DB m Doc
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
@ -385,10 +402,11 @@ inlineToDocbook opts (Link attr txt (src, _))
_ -> do contents <- inlinesToDocbook opts txt _ -> do contents <- inlinesToDocbook opts txt
return $ contents <+> return $ contents <+>
char '(' <> emailLink <> char ')' char '(' <> emailLink <> char ')'
| otherwise = | otherwise = do
version <- ask
(if isPrefixOf "#" src (if isPrefixOf "#" src
then inTags False "link" $ ("linkend", drop 1 src) : idAndRole attr then inTags False "link" $ ("linkend", drop 1 src) : idAndRole attr
else if writerDocbook5 opts else if version == DocBook5
then inTags False "link" $ ("xlink:href", src) : idAndRole attr then inTags False "link" $ ("xlink:href", src) : idAndRole attr
else inTags False "ulink" $ ("url", src) : idAndRole attr ) else inTags False "ulink" $ ("url", src) : idAndRole attr )
<$> inlinesToDocbook opts txt <$> inlinesToDocbook opts txt

View file

@ -99,7 +99,7 @@ tests = [ testGroup "markdown"
"textile-reader.textile" "textile-reader.native" "textile-reader.textile" "textile-reader.native"
] ]
, testGroup "docbook" , testGroup "docbook"
[ testGroup "writer" $ writerTests "docbook" [ testGroup "writer" $ writerTests "docbook4"
, test "reader" ["-r", "docbook", "-w", "native", "-s"] , test "reader" ["-r", "docbook", "-w", "native", "-s"]
"docbook-reader.docbook" "docbook-reader.native" "docbook-reader.docbook" "docbook-reader.native"
, test "reader" ["-r", "docbook", "-w", "native", "-s"] , test "reader" ["-r", "docbook", "-w", "native", "-s"]

View file

@ -11,7 +11,7 @@ docbook :: (ToPandoc a) => a -> String
docbook = docbookWithOpts def{ writerWrapText = WrapNone } docbook = docbookWithOpts def{ writerWrapText = WrapNone }
docbookWithOpts :: ToPandoc a => WriterOptions -> a -> String docbookWithOpts :: ToPandoc a => WriterOptions -> a -> String
docbookWithOpts opts = purely (writeDocbook opts) . toPandoc docbookWithOpts opts = purely (writeDocbook4 opts) . toPandoc
{- {-
"my test" =: X =?> Y "my test" =: X =?> Y