diff options
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | RELEASE-CHECKLIST | 3 | ||||
| -rw-r--r-- | changelog | 32 | ||||
| m--------- | data/templates | 12 | ||||
| -rwxr-xr-x | make_osx_package.sh | 6 | ||||
| -rw-r--r-- | pandoc.cabal | 22 | ||||
| -rw-r--r-- | pandoc.hs | 15 | ||||
| -rw-r--r-- | src/Text/Pandoc/Readers/HTML.hs | 18 | ||||
| -rw-r--r-- | src/Text/Pandoc/Writers/Docx.hs | 16 | ||||
| -rw-r--r-- | trypandoc/Makefile | 14 | ||||
| -rw-r--r-- | trypandoc/index.html | 137 | ||||
| -rw-r--r-- | trypandoc/trypandoc.hs | 100 |
12 files changed, 353 insertions, 29 deletions
@@ -5,7 +5,7 @@ ifeq "${makemanpages}" "" endif setup=dist/setup/setup MANPAGES=man/man1/pandoc.1 man/man5/pandoc_markdown.5 -CABALARGS=-fmake-pandoc-man-pages --enable-tests --enable-benchmarks +CABALARGS=-fmake-pandoc-man-pages -ftrypandoc --enable-tests --enable-benchmarks all: build test @@ -44,6 +44,9 @@ dist: sdist man: ${MANPAGES} +osxpkg: + ./make_osx_package.sh + %.1: %.1.template ${makemanpages} @@ -53,4 +56,4 @@ man: ${MANPAGES} clean: -rm ${MANPAGES} -.PHONY: all man clean test build bench haddock sdist +.PHONY: all man clean test build bench haddock sdist osxpkg diff --git a/RELEASE-CHECKLIST b/RELEASE-CHECKLIST index a8237211c..0663e3f3a 100644 --- a/RELEASE-CHECKLIST +++ b/RELEASE-CHECKLIST @@ -20,7 +20,8 @@ _ Update website, including short description of changes _ Announce on pandoc-announce, pandoc-discuss -_ recompile trypandoc +_ on server, 'cabal install --enable-tests -ftrypandoc' + and then 'cd trypandoc; sudo make install' _ recompile gitit @@ -1,3 +1,35 @@ +pandoc (1.13.0.1) + + * Docx writer: + + + Fixed regression which bungled list numbering (#1544), causing + all lists to appear as basic ordered lists. + + Include row width in table rows (Christoffer Ackelman, Viktor Kronvall). + Added a property to all table rows where the sum of column widths + is specified in pct (fraction of 5000). This helps persuade Word + to lay out the table with the widths we specify. + + * Fixed a bug in Windows 8 which caused pandoc not to find the + `pandoc-citeproc` filter (#1542). + + * Docx reader: miscellaneous under-the-hood improvements (Jesse Rosenthal). + Most significantly, the reader now uses Builder, leading to some + performance improvements. + + * HTML reader: Parse appropriately styled span as SmallCaps. + + * Markdown writer: don't escape `$`, `^`, `~` when `tex_math_dollars`, + `superscript`, and `subscript` extensions, respectively, are + deactivated (#1127). + + * Added `trypandoc` flag to build CGI executable used in the online + demo. + + * Makefile: Added 'quick', 'osxpkg' targets. + + * Updated README in templates to indicate templates license. + The templates are dual-licensed, BSD3 and GPL2+. + pandoc (1.13) [new features] diff --git a/data/templates b/data/templates -Subproject 950b54c55c5e6577a09715d9654abafac445ab5 +Subproject ecb769cb7b4354234135c030dcb03a064f03947 diff --git a/make_osx_package.sh b/make_osx_package.sh index ac6427af1..6030f7032 100755 --- a/make_osx_package.sh +++ b/make_osx_package.sh @@ -12,7 +12,6 @@ SCRIPTS=$OSX/osx-resources BASE=pandoc-$VERSION ME=$(whoami) PACKAGEMAKER=/Applications/PackageMaker.app/Contents/MacOS/PackageMaker -EXES="pandoc pandoc-citeproc" CPPHS=$SANDBOX/bin/cpphs # echo Removing old files... @@ -27,8 +26,7 @@ echo Building pandoc... cabal clean # Use cpphs to avoid problems with clang cpp on ghc 7.8 osx: cabal install cpphs hsb2hs -cabal install --ghc-options="-optl-mmacosx-version-min=10.6" --reinstall --flags="embed_data_files make-pandoc-man-pages" --ghc-options "-pgmP$CPPHS -optP--cpp" -cabal install --ghc-options="-optl-mmacosx-version-min=10.6" --reinstall --flags="embed_data_files" pandoc-citeproc --ghc-options "-pgmP$CPPHS -optP--cpp" +cabal install --ghc-options="-optl-mmacosx-version-min=10.6" --reinstall --flags="embed_data_files make-pandoc-man-pages" --ghc-options "-pgmP$CPPHS -optP--cpp" . pandoc-citeproc make man # get pandoc-citeproc man page: @@ -38,7 +36,7 @@ cp $PANDOC_CITEPROC_PATH/man/man1/pandoc-citeproc.1 $MANDIR/man1/ mkdir -p $DEST/bin mkdir -p $DEST/share/man/man1 mkdir -p $DEST/share/man/man5 -for f in $EXES; do +for f in pandoc pandoc-citeproc; do cp $SANDBOX/bin/$f $DEST/bin/; cp $MANDIR/man1/$f.1 $DEST/share/man/man1/ done diff --git a/pandoc.cabal b/pandoc.cabal index 3486ad48c..882397ba4 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -1,5 +1,5 @@ Name: pandoc -Version: 1.13 +Version: 1.13.0.1 Cabal-Version: >= 1.10 Build-Type: Custom License: GPL @@ -93,6 +93,9 @@ Extra-Source-Files: -- generated man pages (produced post-build) man/man1/pandoc.1 man/man5/pandoc_markdown.5 + -- trypandoc + trypandoc/Makefile + trypandoc/index.html -- tests tests/bodybg.gif tests/*.native @@ -116,6 +119,8 @@ Extra-Source-Files: tests/s5-inserts.html tests/tables.context tests/tables.docbook + tests/tables.dokuwiki + tests/tables.icml tests/tables.html tests/tables.latex tests/tables.man @@ -184,6 +189,10 @@ Flag embed_data_files Description: Embed data files in binary for relocatable executable. Default: False +Flag trypandoc + Description: Build trypandoc cgi executable. + Default: False + Flag https Description: Enable support for downloading of resources over https. Default: True @@ -352,6 +361,17 @@ Executable pandoc Main-Is: pandoc.hs Buildable: True +Executable trypandoc + Main-Is: trypandoc.hs + Hs-Source-Dirs: trypandoc + build-depends: base, aeson, pandoc, highlighting-kate, + text, wai-extra, wai >= 0.3, http-types + default-language: Haskell2010 + if flag(trypandoc) + Buildable: True + else + Buildable: False + -- NOTE: A trick in Setup.hs makes sure this won't be installed: Executable make-pandoc-man-pages Main-Is: make-pandoc-man-pages.hs @@ -44,7 +44,7 @@ import Text.Pandoc.SelfContained ( makeSelfContained ) import Text.Pandoc.Process (pipeProcess) import Text.Highlighting.Kate ( languages, Style, tango, pygments, espresso, zenburn, kate, haddock, monochrome ) -import System.Environment ( getArgs, getProgName, getEnvironment ) +import System.Environment ( getArgs, getProgName ) import System.Exit ( exitWith, ExitCode (..) ) import System.FilePath import System.Console.GetOpt @@ -113,12 +113,15 @@ isTextFormat s = takeWhile (`notElem` "+-") s `notElem` binaries externalFilter :: FilePath -> [String] -> Pandoc -> IO Pandoc externalFilter f args' d = do - mbPath <- lookup "PATH" <$> getEnvironment - mbexe <- if '/' `elem` f || mbPath == Nothing - -- don't check PATH if filter name has a path, or - -- if the PATH is not set + mbexe <- if '/' `elem` f + -- don't check PATH if filter name has a path then return Nothing - else findExecutable f + -- we catch isDoesNotExistError because this will + -- be triggered if PATH not set: + else E.catch (findExecutable f) + (\e -> if isDoesNotExistError e + then return Nothing + else throwIO e) (f', args'') <- case mbexe of Just x -> return (x, args') Nothing -> do diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs index bd60a74fa..4ea5f41d5 100644 --- a/src/Text/Pandoc/Readers/HTML.hs +++ b/src/Text/Pandoc/Readers/HTML.hs @@ -91,16 +91,20 @@ replaceNotes' x = return x data HTMLState = HTMLState { parserState :: ParserState, - noteTable :: [(String, Blocks)] + noteTable :: [(String, Blocks)] } data HTMLLocal = HTMLLocal { quoteContext :: QuoteContext , inChapter :: Bool -- ^ Set if in chapter section + , inPlain :: Bool -- ^ Set if in pPlain } setInChapter :: HTMLParser s a -> HTMLParser s a setInChapter = local (\s -> s {inChapter = True}) +setInPlain :: HTMLParser s a -> HTMLParser s a +setInPlain = local (\s -> s {inPlain = True}) + type HTMLParser s = ParserT s HTMLState (Reader HTMLLocal) type TagParser = HTMLParser [Tag String] @@ -141,8 +145,8 @@ block = do , pTable , pHead , pBody - , pPlain , pDiv + , pPlain , pRawHtmlBlock ] when tr $ trace (printf "line %d: %s" (sourceLine pos) @@ -422,7 +426,7 @@ pBlockQuote = do pPlain :: TagParser Blocks pPlain = do - contents <- trimInlines . mconcat <$> many1 inline + contents <- setInPlain $ trimInlines . mconcat <$> many1 inline if B.isNull contents then return mempty else return $ B.plain contents @@ -579,7 +583,11 @@ pSpan = try $ do pRawHtmlInline :: TagParser Inlines pRawHtmlInline = do - result <- pSatisfy (tagComment (const True)) <|> pSatisfy isInlineTag + inplain <- asks inPlain + result <- pSatisfy (tagComment (const True)) + <|> if inplain + then pSatisfy (not . isBlockTag) + else pSatisfy isInlineTag parseRaw <- getOption readerParseRaw if parseRaw then return $ B.rawInline "html" $ renderTags' [result] @@ -919,7 +927,7 @@ instance HasMeta HTMLState where deleteMeta s st = st {parserState = deleteMeta s $ parserState st} instance Default HTMLLocal where - def = HTMLLocal NoQuote False + def = HTMLLocal NoQuote False False instance HasLastStrPosition HTMLState where setLastStrPos s st = st {parserState = setLastStrPos s (parserState st)} diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs index 38031b7dc..fbf38e6f1 100644 --- a/src/Text/Pandoc/Writers/Docx.hs +++ b/src/Text/Pandoc/Writers/Docx.hs @@ -114,7 +114,13 @@ type WS a = StateT WriterState IO a mknode :: Node t => String -> [(String,String)] -> t -> Element mknode s attrs = - add_attrs (map (\(k,v) -> Attr (unqual k) v) attrs) . node (unqual s) + add_attrs (map (\(k,v) -> Attr (nodename k) v) attrs) . node (nodename s) + +nodename :: String -> QName +nodename s = QName{ qName = name, qURI = Nothing, qPrefix = prefix } + where (name, prefix) = case break (==':') s of + (xs,[]) -> (xs, Nothing) + (ys,(_:zs)) -> (zs, Just ys) toLazy :: B.ByteString -> BL.ByteString toLazy = BL.fromChunks . (:[]) @@ -297,7 +303,8 @@ writeDocx opts doc@(Pandoc meta _) = do -- otherwise things break: [Elem e | e <- allElts , qName (elName e) == "abstractNum" ] ++ - [Elem e | e <- allElts, qName (elName e) == "num" ] } + [Elem e | e <- allElts + , qName (elName e) == "num" ] } let docPropsPath = "docProps/core.xml" let docProps = mknode "cp:coreProperties" [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties") @@ -470,7 +477,7 @@ mkLvl marker lvl = patternFor _ s = s ++ "." getNumId :: WS Int -getNumId = ((999 +) . length) `fmap` gets stLists +getNumId = (((baseListId - 1) +) . length) `fmap` gets stLists -- | Convert Pandoc document to two lists of -- OpenXML elements (the main document and footnotes). @@ -596,12 +603,15 @@ blockToOpenXML opts (Table caption aligns widths headers rows) = do else contents let mkrow border cells = mknode "w:tr" [] $ map (mkcell border) cells let textwidth = 7920 -- 5.5 in in twips, 1/20 pt + let fullrow = 5000 -- 100% specified in pct + let rowwidth = fullrow * sum widths let mkgridcol w = mknode "w:gridCol" [("w:w", show $ (floor (textwidth * w) :: Integer))] () return $ [ mknode "w:tbl" [] ( mknode "w:tblPr" [] ( [ mknode "w:tblStyle" [("w:val","TableNormal")] () ] ++ + [ mknode "w:tblW" [("w:type", "pct"), ("w:w", (show rowwidth))] () ] ++ [ mknode "w:tblCaption" [("w:val", captionStr)] () | not (null caption) ] ) : mknode "w:tblGrid" [] diff --git a/trypandoc/Makefile b/trypandoc/Makefile new file mode 100644 index 000000000..29942ac00 --- /dev/null +++ b/trypandoc/Makefile @@ -0,0 +1,14 @@ +CGIBIN=/home/website/cgi-bin +TRYPANDOC=/home/website/html/pandoc/try/ +CGI=${CGIBIN}/trypandoc +BIN=../dist/build/trypandoc/trypandoc + +install: ${CGI} ${TRYPANDOC}/index.html + +${TRYPANDOC}/%: % + cp $< $@ && chown website:www-data $@ && chmod a+r $@ + +${CGI}: ${BIN} + cp $< $@ && chown website:www-data $@ && chmod a+rx $@ + +.PHONY: install diff --git a/trypandoc/index.html b/trypandoc/index.html new file mode 100644 index 000000000..2c9c55ef2 --- /dev/null +++ b/trypandoc/index.html @@ -0,0 +1,137 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Try pandoc!</title> + <script src="//code.jquery.com/jquery-1.11.0.min.js"></script> + <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> + <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> + <script type="text/javascript"> +(function($) { // http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values + $.QueryString = (function(a) { + if (a == "") return {}; + var b = {}; + for (var i = 0; i < a.length; ++i) + { + var p=a[i].split('='); + if (p.length != 2) continue; + b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " ")); + } + return b; + })(window.location.search.substr(1).split('&')) +})(jQuery); + +function newpage() { + var input = $("#text").val(); + var from = $("#from").val(); + var to = $("#to").val(); + var href = window.location.href; + window.location.href = href.replace(/([?].*)?$/,"?" + $.param({text: input, from: from, to: to})); +}; + +function process(res) { + $("#results").text(res.result); + $("#version").text(res.version); +} + +$(document).ready(function() { + var text = $.QueryString["text"]; + $("#text").val(text); + var from = $.QueryString["from"] || "markdown"; + $("#from").val(from); + var to = $.QueryString["to"] || "html"; + $("#to").val(to); + if (text && text != "") { + $.getJSON("http://johnmacfarlane.net/cgi-bin/trypandoc", { from: from, to: to, text: text }, process); + }; + $("#convert").click(newpage); +}); + </script> + <style type="text/css"> + h1 { margin-bottom: 1em; } + body { margin: auto; } + textarea { height: auto; width: 100%; font-family: monospace; margin-top: 15px; } + div.alert { margin: 1em; } + h3 { margin-top: 0; margin-bottom: 0; padding: 0; font-size: 100%; } + pre#results { width: 100%; margin-top: 15px; } + footer { color: #555; text-align: center; margin: 1em; } + p.version { color: #555; } + button#convert { vertical-align: bottom; } + </style> +</head> +<body> +<div class="container"> + <div class="row"> + <h1>Try <a href="http://johnmacfarlane.net/pandoc/">pandoc</a>!</h1> + </div> + <div class="row"> + <div class="col-md-6"> + <label for="from"> + from + </label> + <select id="from"> + <option value="markdown" selected>Markdown</option> + <option value="markdown_strict">Markdown/strict</option> + <option value="markdown_phpextra">PHP Markdown Extra</option> + <option value="markdown_github">Github Markdown</option> + <option value="markdown_mmd">MultiMarkdown</option> + <option value="rst">reStructuredText</option> + <option value="textile">Textile</option> + <option value="latex">LaTeX</option> + <option value="html">HTML</option> + <option value="docbook">DocBook</option> + <option value="opml">OPML</option> + <option value="org">Emacs Org Mode</option> + <option value="t2t">Txt2Tags</option> + <option value="mediawiki">MediaWiki</option> + <option value="haddock">Haddock markup</option> + </select> + <br/> + <textarea id="text" maxlength="3000" rows="15"></textarea> + </div> + <div class="col-md-6"> + <label for="to"> + to + </label> + <select id="to"> + <option value="html" selected>HTML</option> + <option value="html5">HTML 5</option> + <option value="markdown">Markdown</option> + <option value="markdown_strict">Markdown/strict</option> + <option value="markdown_phpextra">PHP Markdown Extra</option> + <option value="markdown_github">Github Markdown</option> + <option value="markdown_mmd">MultiMarkdown</option> + <option value="rst">reStructuredText</option> + <option value="asciidoc">AsciiDoc</option> + <option value="textile">Textile</option> + <option value="mediawiki">MediaWiki</option> + <option value="dokuwiki">DokuWiki</option> + <option value="org">Emacs Org Mode</option> + <option value="latex">LaTeX</option> + <option value="beamer">LaTeX Beamer</option> + <option value="context">ConTeXt</option> + <option value="man">Groff man</option> + <option value="texinfo">Texinfo</option> + <option value="docbook">DocBook</option> + <option value="opml">OPML</option> + <option value="icml">ICML</option> + <option value="opendocument">OpenDocument</option> + <option value="rtf">RTF</option> + <option value="dzslides">DZSlides</option> + <option value="slidy">Slidy</option> + <option value="S5">S5</option> + <option value="slideous">Slideous</option> + </select> + + <button class="btn btn-primary btn-xs" id="convert">Convert</button> + <br/> + <pre id="results"></pre> + </div> + </div> +</div> +<footer> + <p class="version">pandoc <span id="version"></span></p> + <p>© 2013–2014 <a href="http://johnmacfarlane.net">John MacFarlane</a></p> +</footer> +</body> +</html> diff --git a/trypandoc/trypandoc.hs b/trypandoc/trypandoc.hs new file mode 100644 index 000000000..c530f45f2 --- /dev/null +++ b/trypandoc/trypandoc.hs @@ -0,0 +1,100 @@ +{-# LANGUAGE OverloadedStrings #-} +module Main where +import Network.Wai.Handler.CGI +import Network.Wai +import Control.Applicative ((<$>)) +import Data.Maybe (mapMaybe, fromMaybe) +import Network.HTTP.Types.Status (status200) +import Network.HTTP.Types.Header (hContentType) +import Network.HTTP.Types.URI (queryToQueryText) +import Text.Pandoc +import Text.Pandoc.Shared (tabFilter) +import Text.Highlighting.Kate (pygments) +import Data.Aeson +import qualified Data.Text as T +import Data.Text (Text) + +main :: IO () +main = run app + +app :: Application +app req respond = do + let query = queryToQueryText $ queryString req + let getParam x = maybe (error $ T.unpack x ++ " paramater not set") + return $ lookup x query + text <- getParam "text" >>= checkLength . fromMaybe T.empty + fromFormat <- fromMaybe "" <$> getParam "from" + toFormat <- fromMaybe "" <$> getParam "to" + reader <- maybe (error $ "could not find reader for " ++ T.unpack fromFormat) return + $ lookup fromFormat fromFormats + let writer = maybe (error $ "could not find writer for " ++ T.unpack toFormat) id + $ lookup toFormat toFormats + let result = T.pack $ writer $ reader $ tabFilter 4 $ T.unpack text + let output = encode $ object [ T.pack "result" .= result + , T.pack "name" .= + if fromFormat == "markdown_strict" + then T.pack "pandoc (strict)" + else T.pack "pandoc" + , T.pack "version" .= pandocVersion] + respond $ responseLBS status200 [(hContentType,"text/json; charset=UTF-8")] output + +checkLength :: Text -> IO Text +checkLength t = + if T.length t > 10000 + then error "exceeds length limit of 10,000 characters" + else return t + +writerOpts :: WriterOptions +writerOpts = def { writerReferenceLinks = True, + writerEmailObfuscation = NoObfuscation, + writerHTMLMathMethod = MathJax "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML", + writerHighlight = True, + writerHighlightStyle = pygments } + +readerOpts :: ReaderOptions +readerOpts = def { readerParseRaw = True, + readerSmart = True } + +fromFormats :: [(Text, String -> Pandoc)] +fromFormats = [ + ("native" , readNative) + ,("json" , Text.Pandoc.readJSON readerOpts) + ,("markdown" , readMarkdown readerOpts) + ,("markdown_strict" , readMarkdown readerOpts{ + readerExtensions = strictExtensions, + readerSmart = False }) + ,("markdown_phpextra" , readMarkdown readerOpts{ + readerExtensions = phpMarkdownExtraExtensions }) + ,("markdown_github" , readMarkdown readerOpts{ + readerExtensions = githubMarkdownExtensions }) + ,("markdown_mmd", readMarkdown readerOpts{ + readerExtensions = multimarkdownExtensions }) + ,("rst" , readRST readerOpts) + ,("mediawiki" , readMediaWiki readerOpts) + ,("docbook" , readDocBook readerOpts) + ,("opml" , readOPML readerOpts) + ,("t2t" , readTxt2TagsNoMacros readerOpts) + ,("org" , readOrg readerOpts) + ,("textile" , readTextile readerOpts) -- TODO : textile+lhs + ,("html" , readHtml readerOpts) + ,("latex" , readLaTeX readerOpts) + ,("haddock" , readHaddock readerOpts) + ] + +toFormats :: [(Text, Pandoc -> String)] +toFormats = mapMaybe (\(x,y) -> + case y of + PureStringWriter w -> Just (T.pack x, w writerOpts{ + writerExtensions = + case x of + "markdown_strict" -> strictExtensions + "markdown_phpextra" -> phpMarkdownExtraExtensions + "markdown_mmd" -> multimarkdownExtensions + "markdown_github" -> githubMarkdownExtensions + _ -> pandocExtensions + }) + _ -> + case x of + "rtf" -> Just (T.pack x, writeRTF writerOpts) + _ -> Nothing) writers + |
