pandoc 3.6 → 3.6.1
raw patch · 82 files changed
+637/−184 lines, 82 filesdep ~citeprocdep ~skylightingdep ~skylighting-core
Dependency ranges changed: citeproc, skylighting, skylighting-core
Files
- MANUAL.txt +11/−9
- changelog.md +168/−6
- data/docx/word/document.xml +8/−4
- data/templates/common.latex +0/−3
- data/templates/default.beamer +6/−0
- data/templates/default.latex +3/−0
- data/templates/default.openxml +10/−6
- pandoc.cabal +4/−4
- src/Text/Pandoc/App/OutputSettings.hs +17/−14
- src/Text/Pandoc/Class/PandocMonad.hs +7/−2
- src/Text/Pandoc/Error.hs +1/−1
- src/Text/Pandoc/MIME.hs +13/−12
- src/Text/Pandoc/MediaBag.hs +33/−23
- src/Text/Pandoc/PDF.hs +6/−5
- src/Text/Pandoc/Parsing/General.hs +2/−2
- src/Text/Pandoc/Readers/Docx.hs +6/−10
- src/Text/Pandoc/Readers/HTML.hs +12/−14
- src/Text/Pandoc/Readers/LaTeX.hs +1/−0
- src/Text/Pandoc/Readers/Markdown.hs +14/−2
- src/Text/Pandoc/Readers/Mdoc.hs +2/−2
- src/Text/Pandoc/Readers/MediaWiki.hs +2/−2
- src/Text/Pandoc/Readers/Metadata.hs +13/−9
- src/Text/Pandoc/Readers/RST.hs +7/−10
- src/Text/Pandoc/Readers/Textile.hs +18/−3
- src/Text/Pandoc/Readers/Vimwiki.hs +3/−6
- src/Text/Pandoc/Shared.hs +1/−1
- src/Text/Pandoc/Transforms.hs +5/−0
- src/Text/Pandoc/URI.hs +44/−5
- src/Text/Pandoc/Writers/ANSI.hs +3/−3
- src/Text/Pandoc/Writers/Docx.hs +0/−1
- src/Text/Pandoc/Writers/Docx/OpenXML.hs +23/−8
- src/Text/Pandoc/Writers/HTML.hs +7/−2
- src/Text/Pandoc/Writers/LaTeX.hs +15/−7
- src/Text/Pandoc/Writers/Markdown.hs +5/−3
- src/Text/Pandoc/Writers/MediaWiki.hs +10/−1
- src/Text/Pandoc/Writers/Typst.hs +5/−1
- test/command/10414.md +6/−0
- test/command/10459.md +11/−0
- test/command/10484.md +22/−0
- test/command/10490.md +50/−0
- test/command/10491.md +35/−0
- test/command/6034.md +8/−3
- test/command/9700.md +14/−0
- test/command/9878.md +6/−0
- test/docx/golden/block_quotes.docx binary
- test/docx/golden/codeblock.docx binary
- test/docx/golden/comments.docx binary
- test/docx/golden/custom_style_no_reference.docx binary
- test/docx/golden/custom_style_preserve.docx binary
- test/docx/golden/custom_style_reference.docx binary
- test/docx/golden/definition_list.docx binary
- test/docx/golden/document-properties-short-desc.docx binary
- test/docx/golden/document-properties.docx binary
- test/docx/golden/headers.docx binary
- test/docx/golden/image.docx binary
- test/docx/golden/inline_code.docx binary
- test/docx/golden/inline_formatting.docx binary
- test/docx/golden/inline_images.docx binary
- test/docx/golden/link_in_notes.docx binary
- test/docx/golden/links.docx binary
- test/docx/golden/lists.docx binary
- test/docx/golden/lists_9994.docx binary
- test/docx/golden/lists_continuing.docx binary
- test/docx/golden/lists_div_bullets.docx binary
- test/docx/golden/lists_multiple_initial.docx binary
- test/docx/golden/lists_restarting.docx binary
- test/docx/golden/nested_anchors_in_header.docx binary
- test/docx/golden/notes.docx binary
- test/docx/golden/raw-blocks.docx binary
- test/docx/golden/raw-bookmarks.docx binary
- test/docx/golden/table_one_row.docx binary
- test/docx/golden/table_with_list_cell.docx binary
- test/docx/golden/tables-default-widths.docx binary
- test/docx/golden/tables.docx binary
- test/docx/golden/tables_separated_with_rawblock.docx binary
- test/docx/golden/task_list.docx binary
- test/docx/golden/track_changes_deletion.docx binary
- test/docx/golden/track_changes_insertion.docx binary
- test/docx/golden/track_changes_move.docx binary
- test/docx/golden/track_changes_scrubbed_metadata.docx binary
- test/docx/golden/unicode.docx binary
- test/docx/golden/verbatim_subsuper.docx binary
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: December 7, 2024+date: December 22, 2024 --- # Synopsis@@ -761,14 +761,16 @@ `--template=`*FILE*|*URL* : Use the specified file as a custom template for the generated document.- Implies `--standalone`. See [Templates], below, for a description- of template syntax. If no extension is specified, an extension- corresponding to the writer will be added, so that `--template=special`- looks for `special.html` for HTML output. If the template is not- found, pandoc will search for it in the `templates` subdirectory of- the user data directory (see `--data-dir`). If this option is not used,- a default template appropriate for the output format will be used (see- `-D/--print-default-template`).+ Implies `--standalone`. See [Templates], below, for a+ description of template syntax. If the template is not found,+ pandoc will search for it in the `templates` subdirectory of+ the user data directory (see `--data-dir`). If no extension+ is specified and an extensionless template is not found,+ pandoc will look for a template with an extension+ corresponding to the writer, so that `--template=special`+ looks for `special.html` for HTML output. If this option is+ not used, a default template appropriate for the output+ format will be used (see `-D/--print-default-template`). `-V` *KEY*[`=`*VAL*], `--variable=`*KEY*[`:`*VAL*]
@@ -1,5 +1,167 @@ # Revision history for pandoc +## pandoc 3.6.1 (2024-12-23)++ * Allow YAML bibliographies to be arrays of references (#10452).+ Previously, they had to be YAML objects with a `references` key.++ * Change `--template` to allow use of extensionless templates (#5270).+ The intent is to allow bash process substitution: e.g.,+ `--template <(echo "foo")`. Previously pandoc *always* added an+ extension based on the output format, which caused problems+ with the absolute filenames used by bash process substitution+ (e.g. `/dev/fd/11`). Now, if the template has no extension,+ pandoc will first try to find it without the extension, and+ then add the extension if it can't be found. So, in general,+ extensionless templates can now be used. But this has been+ implemented in a way that should not cause problems for+ existing uses, unless you are using a template `NAME.FORMAT`+ but happen to have an extensionless file `NAME` in the template+ search path.++ * Allow `--shift-heading-level-by=-1` to work in djot in the same way+ it works for other formats (with the top-level heading being+ promoted to metadata title) (#10459). This needed special+ treatment because of the way djot surrounds sections with Divs.++ * RST reader:++ + Handle explicit reference links (#10484, Evan Silberman).+ This case was missed when changing the reference link strategy for+ RST to allow a single pass. (It is a regression in pandoc 3.6.)++ * Markdown reader:++ + Use T.P.URI's `pBase64DataURI` in parsing data URIs (#10075,+ Evan Silberman and John MacFarlane).+ + More efficient base64 data URI parsing (#10075, Evan+ Silberman and John MacFarlane). This should yield dramatic+ performance improvements for markdown documents containing+ large data URIs in images.++ * HTML reader:++ + Don't canonicalize data: URIs (#10075). It can be very expensive+ to call network-uri's URI parser on these.++ * LaTeX reader:++ + Handle `figure*` environment as a figure (#10472).++ * MediaWiki reader:++ + Allow empty quoted attributes (#10490).+ + Allow cells starting with `+` (#10491).++ * Textile reader:++ + Improve parsing of spans (#9878). The span needs to be separated+ from its surroundings by spaces. Also, a span can have attributes,+ which we now attach.+ + Inline constructors shouldn't trigger if closer is preceded by+ whitespace (#10414).++ * Docx writer:++ + Put chapters in separate sections, and restart footnotes+ by section by default (#2773). The main effect of this change is that+ when `--top-level-division=chapter` is used, chapters will start on+ a new page and footnote numbering will restart for each chapter.+ Both of these defaults can be overridden in the reference.docx.+ + Use styleIds not styleNames for Title, Subtitle, etc.+ (#10282). This fixes a regression introduced in pandoc 3.5.+ This change affects the default openxml template as well as the+ OpenXML writer.++ * Markdown writer:++ + Avoid collapsing of initial/final newline in markdown raw blocks.+ This makes it easy to write a filter that adds extra blank lines+ before certain elements (#10477).++ * Mediawiki writer:++ + Escape line-initial characters that would otherwise be interpreted+ as list starts (#9700).++ * LaTeX writer:++ + Properly handle boolean value for `csquotes` variable (#10403).+ + Use displayquote for block quotes with `csquotes` (#10456).++ * HTML writer:++ + Avoid calling parseURIString for data URIs (#10075).+ This was done to determine the "media category," but we can+ get that directly from the mime component of data: URIs.++ * Typst writer:++ + Properly handle data URIs in images (#10460).++ * LaTeX/Beamer templates:++ + Fix default.beamer `nocite` location (Thomas Hodgson).+ It must be inside a frame or it is ignored (#10465).+ + Move nocites from LaTeX preamble to body (#10461, Thomas+ Hodgson). Putting `\nocite` in the preamble works only with biblatex.++ * Text.Pandoc.Parsing:++ + Correct example in comment on `charsInBalanced` (Evan Silberman).++ * Text.Pandoc.Error:++ + Mention typst in rendering `PandocUnknownWriterError` for `pdf`+ (Evan Silberman).++ * Text.Pandoc.MediaBag:++ + `insertMedia`: fast path for data URIs. Avoid the slow URI+ parser from network-uri on large data URIs (#10075).++ * Text.Pandoc.Class:++ + Add shortcut for base64 data URIs in `downloadOrRead` (#10075).+ This avoids calling the slow URI parser from network-uri on+ data URIs, instead calling our own parser.++ * Text.Pandoc.MIME:++ + Fix `extensionFromMimeType`. We had a few special cases encoded,+ but as previously written they wouldn't work properly with+ modifiers like `;charset=utf-8`.++ * Text.Pandoc.URI:++ + Export `pBase64DataURI`. Modify `isURI` to use this and avoid+ calling network-uri's inefficient `parseURI` for data URIs.++ * Text.Pandoc.PDF:++ + Fix temp file extension in `toPdfViaTempFile` (#10468).+ This fixes a regression in pandoc 3.6, which changed+ the extension from `html` to `source`. Apparently+ `wkhtmltopdf` needs it to be `.html`. So now we have added+ a parameter to `toPdfViaTempFile` that allows the extension+ to be specified in a way that is appropriate to the PDF engine+ used.++ * Lua (Albert Krewinkel):++ + Support more elements as input to `pandoc.utils.stringify`+ (#10450). Elements of type Caption, Cell, TableHead, and TableFoot+ can now be stringified.+ + Add `Caption` constructor to `pandoc` module.++ * Miscellaneous code quality improvements (Joseph C. Sible).++ * Depend on citeproc 0.8.1.2, skylighting and skylighting-core+ 0.14.5.++ * `doc/lua-filters.md: Fix links to constructors (Albert Krewinkel).++ ## pandoc 3.6 (2024-12-07) * Add `mdoc` as input format (Evan Silberman). This change@@ -67,8 +229,8 @@ * RST reader: - + Use a new one-pass parsing strategy. Instead of having an initial pass where- we collect reference definitions, we create links with target+ + Use a new one-pass parsing strategy. Instead of having an initial pass+ where we collect reference definitions, we create links with target `##SUBST##something` or `##REF##something` or `##NOTE##something`, and resolve these in a pass over the parsed AST. This allows us to handle link references that are not at the top level (#10281).@@ -94,8 +256,8 @@ * Markdown writer: + Issue INFO warning when not rendering table, e.g., when `raw_html` is- disabled and the table can't be fit into a supported markdown table format- (#10407).+ disabled and the table can't be fit into a supported markdown table+ format (#10407). + Respect empty LineBlock lines in `plain` output (Evan Silberman). The plain writer behaved as a markdown variant with `Ext_line_blocks` turned off, and so empty lines in a line block would get eliminated.@@ -115,8 +277,8 @@ + Make template sensitive to a `page-numbering` variable (#10370). This can be set to an empty string (or, in metadata, to false) for no page numbers.- + Make `smart` extension work (#10271). If `smart` is not enabled, a command in- the default template will disable smartquote substitutions.+ + Make `smart` extension work (#10271). If `smart` is not enabled, a command+ in the default template will disable smartquote substitutions. When `smart` is enabled, render curly apostrophes as straight and escape straight apostrophes. When `smart` is disabled, render curly apostrophes as curly and don't escape straight
@@ -189,7 +189,7 @@ </w:r> <w:r> <w:t xml:space="preserve">- + </w:t> </w:r> <w:r>@@ -207,7 +207,7 @@ </w:r> <w:r> <w:t xml:space="preserve">- + </w:t> </w:r> <w:hyperlink r:id="rId30">@@ -227,7 +227,7 @@ </w:r> <w:r> <w:t xml:space="preserve">- + </w:t> </w:r> <w:r>@@ -391,6 +391,10 @@ </w:t> </w:r> </w:p>- <w:sectPr />+ <w:sectPr>+ <w:footnotePr>+ <w:numRestart w:val="eachSect" />+ </w:footnotePr>+ </w:sectPr> </w:body> </w:document>
@@ -257,9 +257,6 @@ \addbibresource{$bibliography$} $endfor$ $endif$-$if(nocite-ids)$-\nocite{$for(nocite-ids)$$it$$sep$, $endfor$}-$endif$ $-- $-- csquotes $--
@@ -178,6 +178,9 @@ $endif$ $endif$ \begin{frame}[allowframebreaks]{$biblio-title$}+$if(nocite-ids)$+ \nocite{$for(nocite-ids)$$it$$sep$, $endfor$}+$endif$ \bibliographytrue \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} \end{frame}@@ -186,6 +189,9 @@ $endif$ $if(biblatex)$ \begin{frame}[allowframebreaks]{$biblio-title$}+$if(nocite-ids)$+ \nocite{$for(nocite-ids)$$it$$sep$, $endfor$}+$endif$ \bibliographytrue \printbibliography[heading=none] \end{frame}
@@ -96,6 +96,9 @@ $if(has-frontmatter)$ \backmatter $endif$+$if(nocite-ids)$+\nocite{$for(nocite-ids)$$it$$sep$, $endfor$}+$endif$ $if(natbib)$ $if(bibliography)$ $if(biblio-title)$
@@ -4,7 +4,7 @@ $if(title)$ <w:p> <w:pPr>- <w:pStyle w:val="Title" />+ <w:pStyle w:val="$title-style-id$" /> </w:pPr> $title$ </w:p>@@ -12,7 +12,7 @@ $if(subtitle)$ <w:p> <w:pPr>- <w:pStyle w:val="Subtitle" />+ <w:pStyle w:val="$subtitle-style-id$" /> </w:pPr> $subtitle$ </w:p>@@ -20,7 +20,7 @@ $for(author)$ <w:p> <w:pPr>- <w:pStyle w:val="Author" />+ <w:pStyle w:val="$author-style-id$" /> </w:pPr> $author$ </w:p>@@ -28,7 +28,7 @@ $if(date)$ <w:p> <w:pPr>- <w:pStyle w:val="Date" />+ <w:pStyle w:val="$date-style-id$" /> </w:pPr> $date$ </w:p>@@ -37,7 +37,7 @@ $if(abstract-title)$ <w:p> <w:pPr>- <w:pStyle w:val="AbstractTitle" />+ <w:pStyle w:val="$abstract-title-style-id$" /> </w:pPr> <w:r><w:t xml:space="preserve">$abstract-title$</w:t></w:r> </w:p>@@ -64,7 +64,11 @@ $if(sectpr)$ $sectpr$ $else$- <w:sectPr />+ <w:sectPr>+ <w:footnotePr>+ <w:numRestart w:val="eachSect" />+ </w:footnotePr>+ </w:sectPr> $endif$ </w:body> </w:document>
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: pandoc-version: 3.6+version: 3.6.1 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -489,7 +489,7 @@ blaze-markup >= 0.8 && < 0.9, bytestring >= 0.9 && < 0.13, case-insensitive >= 1.2 && < 1.3,- citeproc >= 0.8.1.1 && < 0.9,+ citeproc >= 0.8.1.2 && < 0.9, commonmark >= 0.2.6.1 && < 0.3, commonmark-extensions >= 0.2.5.6 && < 0.3, commonmark-pandoc >= 0.2.2.3 && < 0.3,@@ -524,8 +524,8 @@ random >= 1 && < 1.3, safe >= 0.3.18 && < 0.4, scientific >= 0.3 && < 0.4,- skylighting >= 0.14.4 && < 0.15,- skylighting-core >= 0.14.4 && < 0.15,+ skylighting >= 0.14.5 && < 0.15,+ skylighting-core >= 0.14.5 && < 0.15, split >= 0.2 && < 0.3, syb >= 0.1 && < 0.8, tagsoup >= 0.14.6 && < 0.15,
@@ -25,11 +25,11 @@ import Text.DocTemplates (toVal, Context(..), Val(..)) import qualified Control.Exception as E import Control.Monad-import Control.Monad.Except (throwError)+import Control.Monad.Except (throwError, catchError) import Control.Monad.Trans import Data.Char (toLower) import Data.List (find)-import Data.Maybe (fromMaybe)+import Data.Maybe (catMaybes, fromMaybe) import Skylighting (defaultSyntaxMap) import Skylighting.Parser (addSyntaxDefinition, parseSyntaxDefinition) import System.Directory (getCurrentDirectory)@@ -111,13 +111,15 @@ _ | not standalone -> return Nothing Nothing -> Just <$> getDefault Just tp -> do- -- strip off extensions- let tp' = case takeExtension tp of- "" -> tp <.> T.unpack format- _ -> tp- getTemplate tp'- >>= runWithPartials . compileTemplate tp'- >>= fmap Just . templateOrThrow+ let getAndCompile fp =+ getTemplate fp >>= runWithPartials . compileTemplate fp >>=+ fmap Just . templateOrThrow+ catchError+ (getAndCompile tp)+ (\e ->+ if null (takeExtension tp)+ then getAndCompile (tp <.> T.unpack format)+ else throwError e) (writer, writerExts, mtemplate) <- if "lua" `T.isSuffixOf` format@@ -321,10 +323,11 @@ sandbox' :: (PandocMonad m, MonadIO m) => Opt -> PandocPure a -> m a sandbox' opts = sandbox sandboxedFiles where- sandboxedFiles = maybe id (:) (optReferenceDoc opts) .- maybe id (:) (optEpubMetadata opts) .- maybe id (:) (optEpubCoverImage opts) .- maybe id (:) (optCSL opts) .- maybe id (:) (optCitationAbbreviations opts) $+ sandboxedFiles = catMaybes [ optReferenceDoc opts+ , optEpubMetadata opts+ , optEpubCoverImage opts+ , optCSL opts+ , optCitationAbbreviations opts+ ] ++ optEpubFonts opts ++ optBibliography opts
@@ -77,7 +77,8 @@ import Text.Pandoc.MIME (MimeType, getMimeType) import Text.Pandoc.MediaBag (MediaBag, lookupMedia, MediaItem(..)) import Text.Pandoc.Shared (safeRead, makeCanonical, tshow)-import Text.Pandoc.URI (uriPathToPath)+import Text.Pandoc.URI (uriPathToPath, pBase64DataURI)+import qualified Data.Attoparsec.Text as A import Text.Pandoc.Walk (walkM) import qualified Text.Pandoc.UTF8 as UTF8 import Data.ByteString.Base64 (decodeLenient)@@ -333,7 +334,11 @@ downloadOrRead :: PandocMonad m => T.Text -> m (B.ByteString, Maybe MimeType)-downloadOrRead s = do+downloadOrRead s+ | "data:" `T.isPrefixOf` s,+ Right (bs, mt) <- A.parseOnly pBase64DataURI s+ = pure (bs, Just mt)+ | otherwise = do sourceURL <- getsCommonState stSourceURL case (sourceURL >>= parseURIReference' . ensureEscaped, ensureEscaped s) of (Just u, s') -> -- try fetching from relative path at source
@@ -129,7 +129,7 @@ "Unknown output format " <> w <> case w of "pdf" -> "To create a pdf using pandoc, use" <>- " -t latex|beamer|context|ms|html5" <>+ " -t latex|beamer|context|ms|html5|typst" <> "\nand specify an output file with " <> ".pdf extension (-o filename.pdf)." "doc" -> "\nPandoc can convert to DOCX, but not to DOC."
@@ -45,20 +45,21 @@ getMimeTypeDef = fromMaybe "application/octet-stream" . getMimeType extensionFromMimeType :: MimeType -> Maybe T.Text--- few special cases, where there are multiple options:-extensionFromMimeType "text/plain" = Just "txt"-extensionFromMimeType "video/quicktime" = Just "mov"-extensionFromMimeType "video/mpeg" = Just "mpeg"-extensionFromMimeType "video/dv" = Just "dv"-extensionFromMimeType "image/vnd.djvu" = Just "djvu"-extensionFromMimeType "image/tiff" = Just "tiff"-extensionFromMimeType "image/jpeg" = Just "jpg"-extensionFromMimeType "application/xml" = Just "xml"-extensionFromMimeType "application/ogg" = Just "ogg"-extensionFromMimeType "image/svg+xml" = Just "svg" -- avoid svgz extensionFromMimeType mimetype =- M.lookup (T.takeWhile (/=';') mimetype) reverseMimeTypes -- note: we just look up the basic mime type, dropping the content-encoding etc.+ case T.takeWhile (/=';') mimetype of+ -- handle a few special cases, where there are multiple options:+ "text/plain" -> Just "txt"+ "video/quicktime" -> Just "mov"+ "video/mpeg" -> Just "mpeg"+ "video/dv" -> Just "dv"+ "image/vnd.djvu" -> Just "djvu"+ "image/tiff" -> Just "tiff"+ "image/jpeg" -> Just "jpg"+ "application/xml" -> Just "xml"+ "application/ogg" -> Just "ogg"+ "image/svg+xml" -> Just "svg" -- avoid svgz+ mt -> M.lookup mt reverseMimeTypes -- | Determine general media category for file path, e.g. --
@@ -58,6 +58,8 @@ -- | We represent paths with /, in normalized form. Percent-encoding -- is not resolved. canonicalize :: FilePath -> Text+-- avoid an expensive call to isURI for data URIs:+canonicalize fp@('d':'a':'t':'a':':':_) = T.pack fp canonicalize fp | isURI fp = T.pack fp | otherwise = T.replace "\\" "/" . T.pack . normalise $ fp@@ -77,29 +79,37 @@ -> BL.ByteString -- ^ contents of resource -> MediaBag -> MediaBag-insertMedia fp mbMime contents (MediaBag mediamap) =- MediaBag (M.insert fp' mediaItem mediamap)- where mediaItem = MediaItem{ mediaPath = newpath- , mediaContents = contents- , mediaMimeType = mt }- fp' = canonicalize fp- fp'' = unEscapeString $ T.unpack fp'- uri = parseURI fp- newpath = if Posix.isRelative fp''- && Windows.isRelative fp''- && isNothing uri- && not (".." `isInfixOf` fp'')- && '%' `notElem` fp''- then fp''- else show (hashWith SHA1 $ BL.toStrict contents) <> ext- fallback = case takeExtension fp'' of- ".gz" -> getMimeTypeDef $ dropExtension fp''- _ -> getMimeTypeDef fp''- mt = fromMaybe fallback mbMime- path = maybe fp'' (unEscapeString . uriPath) uri- ext = case takeExtension path of- '.':e | '%' `notElem` e -> '.':e- _ -> maybe "" (\x -> '.':T.unpack x) $ extensionFromMimeType mt+insertMedia fp mbMime contents (MediaBag mediamap)+ | 'd':'a':'t':'a':':':_ <- fp+ , Just mt' <- mbMime+ = MediaBag (M.insert fp'+ MediaItem{ mediaPath = hashpath+ , mediaContents = contents+ , mediaMimeType = mt' } mediamap)+ | otherwise = MediaBag (M.insert fp' mediaItem mediamap)+ where+ mediaItem = MediaItem{ mediaPath = newpath+ , mediaContents = contents+ , mediaMimeType = mt }+ fp' = canonicalize fp+ fp'' = unEscapeString $ T.unpack fp'+ uri = parseURI fp+ hashpath = show (hashWith SHA1 (BL.toStrict contents)) <> ext+ newpath = if Posix.isRelative fp''+ && Windows.isRelative fp''+ && isNothing uri+ && not (".." `isInfixOf` fp'')+ && '%' `notElem` fp''+ then fp''+ else hashpath+ fallback = case takeExtension fp'' of+ ".gz" -> getMimeTypeDef $ dropExtension fp''+ _ -> getMimeTypeDef fp''+ mt = fromMaybe fallback mbMime+ path = maybe fp'' (unEscapeString . uriPath) uri+ ext = case takeExtension path of+ '.':e | '%' `notElem` e -> '.':e+ _ -> maybe "" (\x -> '.':T.unpack x) $ extensionFromMimeType mt -- | Lookup a media item in a 'MediaBag', returning mime type and contents. lookupMedia :: FilePath
@@ -91,12 +91,12 @@ else [f] source <- writer opts doc verbosity <- getVerbosity- liftIO $ toPdfViaTempFile verbosity program pdfargs mkOutArgs source+ liftIO $ toPdfViaTempFile verbosity program pdfargs mkOutArgs ".html" source "typst" -> do source <- writer opts doc verbosity <- getVerbosity liftIO $- toPdfViaTempFile verbosity program ("compile":pdfargs) (:[]) source+ toPdfViaTempFile verbosity program ("compile":pdfargs) (:[]) ".typ" source "pdfroff" -> do source <- writer opts doc let paperargs =@@ -184,7 +184,7 @@ -- see #6474 source <- writer opts doc verbosity <- getVerbosity- liftIO $ toPdfViaTempFile verbosity program args (:[]) source+ liftIO $ toPdfViaTempFile verbosity program args (:[]) ".html" source handleImages :: (PandocMonad m, MonadIO m) => WriterOptions@@ -469,10 +469,11 @@ -> String -- ^ Program (program name or path) -> [String] -- ^ Args to program -> (String -> [String]) -- ^ Construct args for output file+ -> String -- ^ extension to use for input file (e.g. '.html') -> Text -- ^ Source -> IO (Either ByteString ByteString)-toPdfViaTempFile verbosity program args mkOutArgs source =- withTempFile "." "toPdfViaTempFile.source" $ \file h1 ->+toPdfViaTempFile verbosity program args mkOutArgs extension source =+ withTempFile "." ("toPdfViaTempFile" <> extension) $ \file h1 -> withTempFile "." "toPdfViaTempFile.pdf" $ \pdfFile h2 -> do hClose h1 hClose h2
@@ -446,8 +446,8 @@ -- | Parse a string of characters between an open character -- and a close character, including text between balanced -- pairs of open and close, which must be different. For example,--- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"--- and return "hello (there)".+-- @charsInBalanced '(' ')' (Data.Text.singleton <$> anyChar)@ will parse+-- "(hello (there))" and return "hello (there)". charsInBalanced :: (Stream s m Char, UpdateSourcePos s Char) => Char -> Char -> ParsecT s st m Text -> ParsecT s st m Text charsInBalanced open close parser = try $ do
@@ -547,16 +547,12 @@ , citationHash = 0 } let items = Citeproc.citationItems citation let cs = map toPandocCitation items- refs <- mapM (traverse (return . text)) $- mapMaybe (\item ->- case Citeproc.citationItemData item of- Nothing -> Nothing- Just itemData ->- -- see #10366, sometimes itemData has a different- -- id and we need to use the same one:- Just $ itemData{ referenceId =- Citeproc.citationItemId item })- items+ let refs = mapMaybe (\item -> fmap (\itemData -> text <$>+ -- see #10366, sometimes itemData has a different+ -- id and we need to use the same one:+ itemData{ referenceId =+ Citeproc.citationItemId item })+ (Citeproc.citationItemData item)) items modify $ \st -> st{ docxReferences = foldr (\ref -> M.insert (referenceId ref) ref)
@@ -927,25 +927,21 @@ let attr = toStringAttr attr' unless inCase $ guard (maybe True (== mathMLNamespace) (lookup "xmlns" attr))- let isDisplay = case lookup "display" attr of- Just "block" -> True- _ -> False+ let constructor = case lookup "display" attr of+ Just "block" -> B.displayMath+ _ -> B.math contents <- manyTill pAny (pSatisfy (matchTagClose "math")) -- KaTeX and others include original TeX in annotation tag; -- just use this if present rather than parsing MathML: case extractTeXAnnotation contents of- Just x -> return $ if isDisplay- then B.displayMath x- else B.math x+ Just x -> return $ constructor x Nothing -> case mathMLToTeXMath (renderTags $ [open] <> contents <> [TagClose "math"]) of Left _ -> return $ B.spanWith ("",["math"],attr) $ B.text $ innerText contents Right "" -> return mempty- Right x -> return $ if isDisplay- then B.displayMath x- else B.math x+ Right x -> return $ constructor x extractTeXAnnotation :: [Tag Text] -> Maybe Text extractTeXAnnotation [] = Nothing@@ -1226,8 +1222,10 @@ -- | Adjusts a url according to the document's base URL. canonicalizeUrl :: PandocMonad m => Text -> TagParser m Text-canonicalizeUrl url = do- mbBaseHref <- baseHref <$> getState- return $ case (parseURIReference (T.unpack url), mbBaseHref) of- (Just rel, Just bs) -> tshow (rel `nonStrictRelativeTo` bs)- _ -> url+canonicalizeUrl url+ | "data:" `T.isPrefixOf` url = return url+ | otherwise = do+ mbBaseHref <- baseHref <$> getState+ return $ case (parseURIReference (T.unpack url), mbBaseHref) of+ (Just rel, Just bs) -> tshow (rel `nonStrictRelativeTo` bs)+ _ -> url
@@ -1016,6 +1016,7 @@ , ("minipage", divWith ("",["minipage"],[]) <$> env "minipage" (skipopts *> spaces *> optional braced *> spaces *> blocks)) , ("figure", env "figure" $ skipopts *> figure')+ , ("figure*", env "figure*" $ skipopts *> figure') , ("subfigure", env "subfigure" $ skipopts *> tok *> figure') , ("center", divWith ("", ["center"], []) <$> env "center" blocks) , ("quote", blockQuote <$> env "quote" blocks)
@@ -28,6 +28,7 @@ import qualified Data.Map as M import Data.Maybe import qualified Data.Set as Set+import qualified Data.Attoparsec.Text as A import Data.Text (Text) import qualified Data.Text as T import qualified Data.ByteString as BS@@ -51,7 +52,7 @@ isCommentTag, isInlineTag, isTextTag) import Text.Pandoc.Readers.LaTeX (applyMacros, rawLaTeXBlock, rawLaTeXInline) import Text.Pandoc.Shared-import Text.Pandoc.URI (escapeURI, isURI)+import Text.Pandoc.URI (escapeURI, isURI, pBase64DataURI) import Text.Pandoc.XML (fromEntities) import Text.Pandoc.Readers.Metadata (yamlBsToMeta, yamlBsToRefs, yamlMetaBlock) -- import Debug.Trace (traceShowId)@@ -1834,11 +1835,22 @@ let sourceURL = T.unwords . T.words . T.concat <$> many urlChunk let betweenAngles = try $ char '<' >> mconcat <$> (manyTill litChar (char '>'))- src <- try betweenAngles <|> sourceURL+ src <- try betweenAngles <|> try base64DataURI <|> sourceURL tit <- option "" $ try $ spnl >> linkTitle skipSpaces char ')' return (escapeURI $ trimr src, tit)++base64DataURI :: PandocMonad m => ParsecT Sources s m Text+base64DataURI = do+ Sources ((pos, txt):rest) <- getInput+ let r = A.parse (fst <$> A.match pBase64DataURI) txt+ case r of+ A.Done remaining consumed -> do+ let pos' = incSourceColumn pos (T.length consumed)+ setInput $ Sources ((pos', remaining):rest)+ return consumed+ _ -> mzero linkTitle :: PandocMonad m => MarkdownParser m Text linkTitle = quotedTitle '"' <|> quotedTitle '\''
@@ -26,7 +26,7 @@ #if MIN_VERSION_base(4,19,0) import Data.List (intersperse, unsnoc) #else-import Data.List (intersperse, uncons)+import Data.List (intersperse) #endif import qualified Data.Map.Strict as M import qualified Data.Text as T@@ -46,7 +46,7 @@ #if !MIN_VERSION_base(4,19,0) unsnoc :: [a] -> Maybe ([a], a)-unsnoc xs = (\(hd, tl) -> (reverse tl, hd)) <$> uncons (reverse xs)+unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing #endif {- As a general principle, if mandoc -T lint issues a WARNING admonition
@@ -253,7 +253,7 @@ skipMany spaceChar char '=' skipMany spaceChar- v <- (char '"' >> many1TillChar (satisfy (/='\n')) (char '"'))+ v <- (char '"' >> manyTillChar (satisfy (/='\n')) (char '"')) <|> many1Char (satisfy $ \c -> not (isSpace c) && c /= '|') return (k,v) @@ -276,7 +276,7 @@ skipMany spaceChar c <- oneOf "|!" when (col > 1) $ void $ char c- notFollowedBy (oneOf "-}+")+ notFollowedBy (oneOf "-}") attribs <- option [] (parseAttrs <* skipMany spaceChar <* char '|') skipMany spaceChar pure attribs
@@ -21,6 +21,7 @@ import Control.Monad.Except (throwError) import qualified Data.ByteString as B import qualified Data.Map as M+import qualified Data.Vector as V import Data.Text (Text) import qualified Data.Text as T import qualified Data.Yaml as Yaml@@ -46,8 +47,7 @@ case decodeAllWithWarnings bstr of Right (warnings, xs) -> do pos <- getPosition- mapM_ (\w -> case w of- Yaml.DuplicateKey jpath ->+ mapM_ (\(Yaml.DuplicateKey jpath) -> report (YamlWarning pos $ "Duplicate key: " <> T.pack (formatRelativePath jpath))) warnings@@ -84,20 +84,24 @@ yamlBsToRefs pMetaValue idpred bstr = case Yaml.decodeAllEither' bstr of Right (Object m : _) -> do- let isSelected (String t) = idpred t- isSelected _ = False- let hasSelectedId (Object o) =- case parse (withObject "ref" (.:? "id")) (Object o) of- Success (Just id') -> isSelected id'- _ -> False- hasSelectedId _ = False case parse (withObject "metadata" (.:? "references")) (Object m) of Success (Just refs) -> sequence <$> mapM (yamlToMetaValue pMetaValue) (filter hasSelectedId refs) _ -> return $ return []+ Right (Array v : _) -> do+ let refs = filter hasSelectedId $ V.toList v+ sequence <$> mapM (yamlToMetaValue pMetaValue) (filter hasSelectedId refs) Right _ -> return . return $ [] Left err' -> throwError $ PandocParseError $ T.pack $ Yaml.prettyPrintParseException err'+ where+ isSelected (String t) = idpred t+ isSelected _ = False+ hasSelectedId (Object o) =+ case parse (withObject "ref" (.:? "id")) (Object o) of+ Success (Just id') -> isSelected id'+ _ -> False+ hasSelectedId _ = False normalizeMetaValue :: (PandocMonad m, HasLastStrPosition st) => ParsecT Sources st m (Future st MetaValue)
@@ -1704,22 +1704,19 @@ skipSpaces string "`_" optional $ char '_' -- anonymous form- ((src',tit),attr) <-- if isURI src- then return ((src, ""), nullAttr)- else- case T.unsnoc src of- -- `link <google_>` is a reference link to _google!- Just (xs, '_') -> lookupKey [] (toKey xs)- _ -> return ((src, ""), nullAttr)+ let src' | isURI src = escapeURI src+ | otherwise =+ case T.unsnoc src of+ Just (xs, '_') -> "##REF##" <> xs+ _ -> src let label'' = if label' == mempty then B.str src else label' let key = toKey $ stringify label' unless (key == Key mempty) $ do updateState $ \s -> s{- stateKeys = M.insert key ((src',tit), attr) $ stateKeys s }- return $ B.linkWith attr (escapeURI src') tit label''+ stateKeys = M.insert key ((src',""), nullAttr) $ stateKeys s }+ return $ B.linkWith nullAttr src' "" label'' citationName :: PandocMonad m => RSTParser m Text citationName = do
@@ -501,6 +501,7 @@ , endline , code , escapedInline+ , spanGroup , inlineMarkup , groupedInlineMarkup , rawHtmlInline@@ -525,9 +526,21 @@ , simpleInline (char '-' <* notFollowedBy (char '-')) B.strikeout , simpleInline (char '^') B.superscript , simpleInline (char '~') B.subscript- , simpleInline (char '%') id ] +-- "The <span> tag is created by percent % signs between whitespaces."+-- e.g. My mother has %{color:green;}green% eyes.+spanGroup :: PandocMonad m => TextileParser m Inlines+spanGroup = try $ do+ notAfterString >>= guard+ char '%' *> notFollowedBy whitespace+ attr <- option nullAttr attributes+ contents <- mconcat <$> manyTill+ (try (((B.space <>) <$> try (whitespace *> notFollowedBy newline *> inline))+ <|> try (notFollowedBy newline *> inline)))+ (try (char '%' <* lookAhead (newline <|> ' ' <$ whitespace)))+ pure $ B.spanWith attr contents+ -- | Trademark, registered, copyright mark :: PandocMonad m => TextileParser m Inlines mark = try $ char '(' >> (try tm <|> try reg <|> copy)@@ -778,12 +791,14 @@ -> (Inlines -> Inlines) -- ^ Inline constructor -> TextileParser m Inlines -- ^ content parser (to be used repeatedly) simpleInline border construct = try $ do- notAfterString+ notAfterString >>= guard border *> notFollowedBy (oneOf " \t\n\r") attr <- attributes body <- trimInlines . mconcat <$> withQuoteContext InSingleQuote- (manyTill (notFollowedBy newline >> inline)+ (manyTill (((B.space <>) <$>+ try (whitespace *> notFollowedBy newline >> inline))+ <|> try (notFollowedBy newline >> inline)) (try border <* notFollowedBy alphaNum)) return $ construct $ if attr == nullAttr
@@ -54,6 +54,7 @@ import Data.Maybe import Data.Text (Text) import qualified Data.Text as T+import Safe (lastMay) import Text.Pandoc.Builder (Blocks, Inlines, fromList, toList, trimInlines) import qualified Text.Pandoc.Builder as B (blockQuote, bulletList, code, codeBlockWith, definitionList,@@ -510,9 +511,7 @@ notFollowedBy (oneOf spaceChars) contents <- mconcat <$> many1Till inline' (try (char '*' *> notFollowedBy alphaNum))- guard $ case reverse (toList contents) of- Space:_ -> False- _ -> True+ guard $ lastMay (toList contents) /= Just Space return $ B.spanWith (makeId contents, [], []) mempty <> B.strong contents makeId :: Inlines -> Text@@ -524,9 +523,7 @@ notFollowedBy (oneOf spaceChars) contents <- mconcat <$> many1Till inline' (try (char '_' *> notFollowedBy alphaNum))- guard $ case reverse (toList contents) of- Space:_ -> False- _ -> True+ guard $ lastMay (toList contents) /= Just Space return $ B.emph contents strikeout :: PandocMonad m => VwParser m Inlines
@@ -523,7 +523,7 @@ where getLevel (Header level _ _) = Min level getLevel _ = Min 99- minLevel = if null numoffsets || all (== 0) numoffsets+ minLevel = if all (== 0) numoffsets then getMin $ query getLevel bs else 1 -- see #5071, for backwards compatibility go :: [Block] -> S.State [Int] [Block]
@@ -154,6 +154,11 @@ | n < 0 , m + n == 0 = headerShift n $ B.setTitle (B.fromList ils) $ Pandoc meta bs+-- for this case, see #10459:+headerShift n (Pandoc meta (Div attr@(_,"section":_,_) (Header m _ ils : as) : bs))+ | n < 0+ , m + n == 0 = headerShift n $+ B.setTitle (B.fromList ils) $ Pandoc meta (Div attr as : bs) headerShift n (Pandoc meta bs) = Pandoc meta (walk shift bs) where
@@ -15,13 +15,20 @@ , isURI , schemes , uriPathToPath+ , pBase64DataURI ) where import qualified Network.HTTP.Types as HTTP+import Data.ByteString.Base64 (decodeLenient)+import Text.Pandoc.MIME (MimeType)+import qualified Data.ByteString as B import qualified Text.Pandoc.UTF8 as UTF8 import qualified Data.Text as T import qualified Data.Set as Set import Data.Char (isSpace, isAscii) import Network.URI (URI (uriScheme), parseURI, escapeURIString)+import qualified Data.Attoparsec.Text as A+import Data.Text.Encoding (encodeUtf8)+import Control.Applicative (many) urlEncode :: T.Text -> T.Text urlEncode = UTF8.toText . HTTP.urlEncode True . UTF8.fromText@@ -90,12 +97,16 @@ -- | Check if the string is a valid URL with a IANA or frequently used but -- unofficial scheme (see @schemes@). isURI :: T.Text -> Bool-isURI =- -- we URI-escape non-ASCII characters because otherwise parseURI will choke:- maybe False hasKnownScheme . parseURI . escapeURIString isAscii . T.unpack+isURI t =+ -- If it's a base 64 data: URI, avoid the expensive call to parseURI:+ case A.parseOnly (pBase64DataURI *> A.endOfInput) t of+ Right () -> True+ Left _ ->+ -- we URI-escape non-ASCII characters because otherwise parseURI will choke:+ maybe False hasKnownScheme . parseURI . escapeURIString isAscii . T.unpack $ t where- hasKnownScheme = (`Set.member` schemes) . T.toLower .- T.filter (/= ':') . T.pack . uriScheme+ hasKnownScheme =+ (`Set.member` schemes) . T.toLower . T.filter (/= ':') . T.pack . uriScheme -- | Converts the path part of a file: URI to a regular path. -- On windows, @/c:/foo@ should be @c:/foo@.@@ -109,3 +120,31 @@ #else path #endif++pBase64DataURI :: A.Parser (B.ByteString, MimeType)+pBase64DataURI = base64uri+ where+ base64uri = do+ A.string "data:"+ mime <- do+ n1 <- restrictedName+ A.char '/'+ n2 <- restrictedName+ mps <- many mediaParam+ pure $ n1 <> "/" <> n2 <> mconcat mps+ A.string ";base64,"+ b64 <- A.takeWhile (A.inClass "A-Za-z0-9+/")+ A.skipWhile (== '=')+ -- this decode should be lazy:+ pure (decodeLenient (encodeUtf8 b64), mime)+ restrictedName = do+ c <- A.satisfy (A.inClass "A-Za-z0-9")+ rest <- A.takeWhile (A.inClass "A-Za-z0-9!#$&^_.+-")+ pure $ T.singleton c <> rest+ mediaParam = do+ A.char ';'+ A.skipWhile isSpace+ k <- restrictedName+ A.char '='+ v <- A.takeWhile (/=';')+ pure $ ";" <> k <> "=" <> v
@@ -82,7 +82,7 @@ body <- blockListToANSI opts blocks' notes <- gets $ reverse . stNotes let notemark x = D.literal (tshow (x :: Int) <> ".") <+> D.space- let marks = take (length notes) $ map notemark [1..]+ let marks = map notemark [1..length notes] let hangWidth = foldr (max . D.offset) 0 marks let notepretty | not (null notes) = D.cblock width hr $+$ hangMarks hangWidth marks notes | otherwise = D.empty@@ -297,12 +297,12 @@ inlineToANSI opts (Superscript lst) = do case traverse toSuperscriptInline lst of Just xs -> inlineListToANSI opts xs- Nothing -> inlineListToANSI opts lst >>= return . D.parens+ Nothing -> D.parens <$> inlineListToANSI opts lst inlineToANSI opts (Subscript lst) = do case traverse toSubscriptInline lst of Just xs -> inlineListToANSI opts xs- Nothing -> inlineListToANSI opts lst >>= return . D.parens+ Nothing -> D.parens <$> inlineListToANSI opts lst inlineToANSI opts (SmallCaps lst) = inlineListToANSI opts lst
@@ -346,7 +346,6 @@ let relEntry = toEntry "word/_rels/document.xml.rels" epochtime $ renderXml reldoc - -- let sectpr = fromMaybe (mknode "w:sectPr" [] ()) mbsectpr' let contents' = BL.fromStrict $ UTF8.fromText contents -- word/document.xml
@@ -286,6 +286,8 @@ (fmap (vcat . map (literal . showContent)) . blocksToOpenXML opts) (fmap (hcat . map (literal . showContent)) . inlinesToOpenXML opts) meta+ cStyleMap <- gets (smParaStyle . stStyleMaps)+ let styleIdOf name = fromStyleId $ getStyleIdFromName name cStyleMap let context = resetField "body" body . resetField "toc" (vcat (map (literal . showElement) toc))@@ -299,6 +301,12 @@ . resetField "date" date . resetField "abstract-title" abstractTitle . resetField "abstract" abstract+ . resetField "title-style-id" (styleIdOf "Title")+ . resetField "subtitle-style-id" (styleIdOf "Subtitle")+ . resetField "author-style-id" (styleIdOf "Author")+ . resetField "date-style-id" (styleIdOf "Date")+ . resetField "abstract-title-style-id" (styleIdOf "AbstractTitle")+ . resetField "abstract-style-id" (styleIdOf "Abstract") $ metadata tpl <- maybe (lift $ compileDefaultTemplate "openxml") pure $ writerTemplate opts let rendered = render Nothing $ renderTemplate tpl context@@ -367,6 +375,7 @@ wrapBookmark ident $ header <> contents blockToOpenXML' opts (Header lev (ident,_,kvs) lst) = do setFirstPara+ let isChapter = lev == 1 && writerTopLevelDivision opts == TopLevelChapter paraProps <- withParaPropM (pStyleM (fromString $ "Heading "++show lev)) $ getParaProps False number <-@@ -380,14 +389,20 @@ Nothing -> return [] else return [] contents <- (number ++) <$> inlinesToOpenXML opts lst- if T.null ident- then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)]- else do- let bookmarkName = ident- modify $ \s -> s{ stSectionIds = Set.insert bookmarkName- $ stSectionIds s }- bookmarkedContents <- wrapBookmark bookmarkName contents- return [Elem $ mknode "w:p" [] (map Elem paraProps ++ bookmarkedContents)]+ let addSectionBreak+ | isChapter = (Elem (mknode "w:p" []+ (mknode "w:pPr" []+ [mknode "w:sectPr" [] ()])) :)+ | otherwise = id+ addSectionBreak <$>+ if T.null ident+ then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)]+ else do+ let bookmarkName = ident+ modify $ \s -> s{ stSectionIds = Set.insert bookmarkName+ $ stSectionIds s }+ bookmarkedContents <- wrapBookmark bookmarkName contents+ return [Elem $ mknode "w:p" [] (map Elem paraProps ++ bookmarkedContents)] blockToOpenXML' opts (Plain lst) = do isInTable <- gets stInTable isInList <- gets stInList
@@ -1578,8 +1578,13 @@ $ toHtml linkTxt , [A5.controls ""] ) s' = fromMaybe s $ T.stripSuffix ".gz" s- normSrc = maybe (T.unpack s) uriPath (parseURIReference $ T.unpack s')- (tag, specAttrs) = case mediaCategory normSrc of+ category =+ if "data:" `T.isPrefixOf` s+ then Just . T.takeWhile (/= '/') . T.drop 5 $ s+ else case parseURIReference (T.unpack s') of+ Just u -> mediaCategory $ uriPath u+ Nothing -> mediaCategory (T.unpack s)+ (tag, specAttrs) = case category of Just "image" -> imageTag Just "video" -> mediaTag H5.video "Video" Just "audio" -> mediaTag H5.audio "Audio"
@@ -39,7 +39,7 @@ import Data.Text (Text) import qualified Data.Text as T import Network.URI (unEscapeString)-import Text.DocTemplates (FromContext(lookupContext), renderTemplate)+import Text.DocTemplates (FromContext(lookupContext), Val(..), renderTemplate) import Text.Collate.Lang (renderLang, Lang(langLanguage)) import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang) import Text.Pandoc.Definition@@ -157,11 +157,15 @@ _ -> "article" when (documentClass `elem` chaptersClasses) $ modify $ \s -> s{ stHasChapters = True }- case lookupContext "csquotes" (writerVariables options) `mplus`- (stringify <$> lookupMeta "csquotes" meta) of- Nothing -> return ()- Just "false" -> return ()- Just _ -> modify $ \s -> s{stCsquotes = True}+ let csquotes =+ case lookupContext "csquotes" (writerVariables options) of+ Just (BoolVal v) -> v+ Just (SimpleVal (Text _ t)) -> t /= ("false" :: Text)+ _ -> case stringify <$> lookupMeta "csquotes" meta of+ Nothing -> False+ Just "false" -> False+ Just _ -> True+ when csquotes $ modify $ \s -> s{stCsquotes = True} let (blocks'', lastHeader) = if writerCiteMethod options == Citeproc then (blocks', []) else case reverse blocks' of@@ -426,6 +430,7 @@ blockToLaTeX $ linesToPara lns blockToLaTeX (BlockQuote lst) = do beamer <- gets stBeamer+ csquotes <- liftM stCsquotes get case lst of [b] | beamer && isListBlock b -> do oldIncremental <- gets stIncremental@@ -438,7 +443,10 @@ modify (\s -> s{stInQuote = True}) contents <- blockListToLaTeX lst modify (\s -> s{stInQuote = oldInQuote})- return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"+ let envname = if csquotes then "displayquote" else "quote"+ return $ ("\\begin" <> braces envname) $$+ contents $$+ ("\\end" <> braces envname) blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do opts <- gets stOptions inNote <- stInNote <$> get
@@ -470,16 +470,18 @@ let renderEmpty = mempty <$ report (BlockNotRendered b) case variant of PlainText- | f == "plain" -> return $ literal str <> literal "\n"+ | f == "plain" -> return $ nest 0 (literal str) <> literal "\n" Commonmark | f `elem` ["gfm", "commonmark", "commonmark_x", "markdown"]- -> return $ literal str $$ blankline+ -> return $ nest 0 (literal str) $$ blankline | f `elem` ["html", "html5", "html4"] -> return $ literal (removeBlankLinesInHTML str) $$ blankline Markdown | f `elem` ["markdown", "markdown_github", "markdown_phpextra", "markdown_mmd", "markdown_strict"]- -> return $ literal str <> literal "\n"+ -- the 'nest 0' ensures that leading and trailing newlines+ -- don't get collapsed. See #10477 for context;+ -> return $ nest 0 (literal str) <> literal "\n" Markua -> renderEmpty _ | f `elem` ["html", "html5", "html4"] , isEnabled Ext_markdown_attribute opts
@@ -117,9 +117,12 @@ tags <- asks useTags lev <- asks listLevel contents <- inlineListToMediaWiki inlines+ let initEsc = if startsWithListMarker contents -- #9700+ then "\\"+ else "" return $ if tags then "<p>" <> contents <> "</p>"- else contents <> if null lev then "\n" else ""+ else initEsc <> contents <> if null lev then "\n" else "" blockToMediaWiki (LineBlock lns) = blockToMediaWiki $ linesToPara lns@@ -1144,3 +1147,9 @@ "yaml", "yaml+jinja", "zephir" ]++startsWithListMarker :: Text -> Bool+startsWithListMarker t =+ case T.uncons t of+ Nothing -> False+ Just (c,_) -> c == '#' || c == ':' || c == ';' || c == '*'
@@ -450,7 +450,11 @@ Just v -> ", " <> literal k <> ": " <> literal v Nothing -> mempty dimAttrs = mconcat $ map toDimAttr ["height", "width"]- coreImage = "image" <> parens (doubleQuoted src' <> dimAttrs)+ isData = "data:" `T.isPrefixOf` src'+ dataSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><image xlink:href=\"" <> src' <> "\" /></svg>"+ coreImage+ | isData = "image.decode" <> parens(doubleQuoted dataSvg <> dimAttrs)+ | otherwise = "image" <> parens (doubleQuoted src' <> dimAttrs) textstyle :: PandocMonad m => Doc Text -> [Inline] -> TW m (Doc Text) textstyle s inlines =
@@ -0,0 +1,6 @@+```+% pandoc -f textile -t html+from 30.-100. text, inside - after dash+^D+<p>from 30.–100. text, inside - after dash</p>+```
@@ -0,0 +1,11 @@+```+% pandoc -s --shift-heading-level-by=-1 -f djot -t native+# hi+^D+Pandoc+ Meta+ { unMeta =+ fromList [ ( "title" , MetaInlines [ Str "hi" ] ) ]+ }+ [ Div ( "hi" , [ "section" ] , [] ) [] ]+```
@@ -0,0 +1,22 @@+```+% pandoc -frst -tmarkdown_strict+- One issue fixed: `issue 123`_.++- One change merged: `Big change <pull 234_>`_.++- Improved the `home page <https://example.com/homepage>`_.++- One more `small change`__.++.. _issue 123: https://github.com/joe/project/issues/123+.. _pull 234: https://github.com/joe/project/pull/234+__ https://github.com/joe/project/issues/999++^D+- One issue fixed: [issue+ 123](https://github.com/joe/project/issues/123).+- One change merged: [Big+ change](https://github.com/joe/project/pull/234).+- Improved the [home page](https://example.com/homepage).+- One more [small change](https://github.com/joe/project/issues/999).+```
@@ -0,0 +1,50 @@+```+% pandoc -f mediawiki -t html+{|class="wikitable" style="text-align: center;"+|-+!rowspan=3 style=""|Witness program version+!colspan=4 style=""|Hash size+|-+!Mainnet+!Testnet+!Mainnet+!Testnet+|-+|0||p2||QW||7Xh||T7n+|-+|1||p4||QY||7Xq||T7w+|}+^D+<table>+<thead>+<tr>+<th style=""><p>Witness program version</p></th>+<th colspan="4" style=""><p>Hash size</p></th>+</tr>+</thead>+<tbody>+<tr>+<td><p>Mainnet</p></td>+<td><p>Testnet</p></td>+<td><p>Mainnet</p></td>+<td><p>Testnet</p></td>+<td></td>+</tr>+<tr>+<td><p>0</p></td>+<td><p>p2</p></td>+<td><p>QW</p></td>+<td><p>7Xh</p></td>+<td><p>T7n</p></td>+</tr>+<tr>+<td><p>1</p></td>+<td><p>p4</p></td>+<td><p>QY</p></td>+<td><p>7Xq</p></td>+<td><p>T7w</p></td>+</tr>+</tbody>+</table>++```
@@ -0,0 +1,35 @@+```+% pandoc -f mediawiki -t gfm+{| class="wikitable"+|-+!+!0+!1+!2+!3+!4+!5+!6+!7+|-+!+0+|q||p||z||r||y||9||x||8+|-+!+8+|g||f||2||t||v||d||w||0+|-+!+16+|s||3||j||n||5||4||k||h+|-+!+24+|c||e||6||m||u||a||7||l+|}+^D+| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |+|-----|-----|-----|-----|-----|-----|-----|-----|-----|+| +0 | q | p | z | r | y | 9 | x | 8 |+| +8 | g | f | 2 | t | v | d | w | 0 |+| +16 | s | 3 | j | n | 5 | 4 | k | h |+| +24 | c | e | 6 | m | u | a | 7 | l |++```
@@ -7,8 +7,13 @@ \end{overpic} \end{figure*} ^D-[ RawBlock- (Format "latex")- "\\begin{figure*}\n \\centering\n \\begin{overpic}{test_pic}\n \\put (70,80) {Caption}\n \\end{overpic}\n\\end{figure*}"+[ Figure+ ( "" , [] , [] )+ (Caption Nothing [])+ [ RawBlock (Format "latex") "\\centering"+ , RawBlock+ (Format "latex")+ "\\begin{overpic}{test_pic}\n \\put (70,80) {Caption}\n \\end{overpic}"+ ] ] ```
@@ -0,0 +1,14 @@+```+% pandoc -t mediawiki+This is a normal sentence with a manual text footnote\*++\* The footnote explains why it couldn't just be inside parentheses++\#foobar \#foobar+^D+This is a normal sentence with a manual text footnote*++\* The footnote explains why it couldn’t just be inside parentheses++\#foobar #foobar+```
@@ -4,3 +4,9 @@ ^D [ Para [ Str "15%" , Space , Str "50%" ] ] ```+```+% pandoc -f textile -t native+15%. 70%+^D+[ Para [ Str "15%." , Space , Str "70%" ] ]+```
binary file changed (10657 → 10691 bytes)
binary file changed (10474 → 10508 bytes)
binary file changed (10805 → 10838 bytes)
binary file changed (10577 → 10611 bytes)
binary file changed (11204 → 11235 bytes)
binary file changed (12436 → 12470 bytes)
binary file changed (10474 → 10506 bytes)
binary file changed (10481 → 10509 bytes)
binary file changed (10967 → 10996 bytes)
binary file changed (10614 → 10651 bytes)
binary file changed (27354 → 27389 bytes)
binary file changed (10413 → 10449 bytes)
binary file changed (10592 → 10626 bytes)
binary file changed (27350 → 27383 bytes)
binary file changed (10635 → 10665 bytes)
binary file changed (10804 → 10840 bytes)
binary file changed (11003 → 11035 bytes)
binary file changed (10758 → 10787 bytes)
binary file changed (10667 → 10702 bytes)
binary file changed (10651 → 10685 bytes)
binary file changed (10885 → 10917 bytes)
binary file changed (10665 → 10699 bytes)
binary file changed (10806 → 10843 bytes)
binary file changed (10583 → 10614 bytes)
binary file changed (10512 → 10542 bytes)
binary file changed (10646 → 10681 bytes)
binary file changed (10487 → 10520 bytes)
binary file changed (10939 → 10972 bytes)
binary file changed (10850 → 10883 bytes)
binary file changed (10863 → 10897 bytes)
binary file changed (10485 → 10517 bytes)
binary file changed (10750 → 10782 bytes)
binary file changed (10457 → 10489 bytes)
binary file changed (10439 → 10472 bytes)
binary file changed (10470 → 10504 bytes)
binary file changed (10584 → 10617 bytes)
binary file changed (10431 → 10466 bytes)
binary file changed (10444 → 10478 bytes)